number 3 should be in array $songsid but when i used in_array method output was null
nuder my function is dd($songsid)
public function index()
{
$songs = Song::latest()->paginate(20);
$songid = Collection::select("song_id")->where("user_id", "=", auth::user()->id)->get();
$songsid = $songid->toArray();
// dd($songsid);
if(in_array(3, $songsid))
{
dd("yes");
}
else
{
dd("no");
}
}
output of $songsid array dd($songsid)
array:2 [▼
0 => array:1 [▼
"song_id" => 3
]
1 => array:1 [▼
"song_id" => 2
]
]
$songsid is not an array of scalar values, but an array of arrays.
You could use array_column() to extract IDs from the array,
in_array(3, array_column($songsid, 'song_id')
Unless you really need to convert to array, you could use collection methods to check that out.
$songid = Collection::select("song_id")->where("user_id", "=", auth::user()->id)->get();
if ($songId->contains('song_id', 3)) ...
In your in_array method, you need an indexed array, ex : $songsid = [3,2]; You can use pluck method :
$songsid = $songid->pluck('id')->toArray();
if(in_array(3, $songsid))
{
dd("yes");
} else {
dd("no");
}
in_array() searches in the array values, that is not nesting.
You may want to use array_culumn() like
in_array(3, array_column($songsid, 'song_id')
or search for ['song_id' => 3] like
in_array(3, array_column($songsid, ['song_id' => 3])
Related
My collection is like this.
Collection {
0 => Name_Model {
"id" => 44
"name" => "The name of "
"list_angg" => Collection {
0 => Name_Model_sub {
"code" => "02"
"nameofcode" => "The name of 02"
}
1 => Name_Model_sub {
"code" => "01"
"nameofcode" => "The name of 01"
}
}
}
1 => Name_Model {
"id" => 45
"name" => "The name of thus"
"list_angg" => Collection {
0 => Name_Model_sub {
"code" => "03"
"nameofcode" => "The name of 3"
}
}
}
}
I want to filter that model by value of list_angg->code. So I try like this. Filter and foreach that list_angg->code
$jurnals = $filterCollection->filter(function($value, $key) use ($kode_fakultas){
foreach ($value->list_angg as $lists) {
$filtered = $lists->where('code', $kode_fakultas);
return $filtered;
}
return $filtered;
});
dd($jurnals);
I try use method reject() and map().
But filter didn't work as well. Is I miss something?
Hope I understood the question correctly.
To filter all elements which list_angg->code has the given value you can use a combination of filter() and contains().
$filterCollection->filter(function ($value) use ($code) {
return $value->list_angg->contains('code', $code);
});
filter() returns all values in a collection which return a truthy value.
contains() returns true or false if a collection contains a value matching the condition provided, which can be a closure, a value or a key and value.
Keep in mind contains() uses "loose" comparison, so if you need a strict match you can use containsStrict.
Your code is not filtering correctly because in the filter closure you are always returning the model instance, which evaluates to true or false based on the first element and therefore it is considered as a pass or fail based on that.
References:
https://laravel.com/docs/8.x/collections#method-contains
https://laravel.com/docs/8.x/collections#method-filter
https://laravel.com/docs/8.x/collections#method-containsstrict
you can do this by first restructuring the collection according to your requirements. For example:
public function formatCollection($collection)
{
$results = [];
foreach ($collection as $item)
{
$results[] = [
'foe' => $item['bar'],
'baz' => $item['foo']
];
}
return collect($results);
}
This will return the required json format and after that you can apply your filters to it. For Example:
$result = formatCollection($collection);
This will return the collection on which you can apply
$result->filter(function(value){
return (value === 'foo');
}
This will return the required information or models you require in your collection.
I have a problem here, I want to combine 2 arrays into 1, I've tried using array_merge from php, and merge () from laravel but nothing works
//$plucked is EAV database
$vendor = Vendor::find($id)->toArray();
$vendor_detail = Vendor_detail::where('vendor_id',$id)->get();
$plucked = $vendor_detail->pluck('vendor_name','vendor_value');
$merged = array_merge($plucked, $vendor);
// $merged = $vendor->merge($plucked)->all();
dd($merged);
I think because the array is different, there array $plucked
#items: array:10 [▼
"user_email" => "cobaupdatelagi#gmail.com"
]
and there my array in $vendor
array:15 [▼
"vendor_id" => 39
"province" => "ACEH"
]
the output that I want
$somearray =[
"vendor_id" => 39
"province" => "ACEH"
"user_email" => "cobaupdatelagi#gmail.com"
]
Your $vendor is one associative array while $plucked is an array of arrays. Even if it has only one item it will be of index zero so you need to loop through $plucked and merge for each one.
$vendor = Vendor::find($id)->toArray();
$vendor_detail = Vendor_detail::where('vendor_id',$id)->get();
$plucked = $vendor_detail->pluck('vendor_name','vendor_value');
$merged = [];
foreach($plucked as $p){
$merged[] = array_merge($p, $vendor);
}
dd($merged);
$vendor = Vendor::find($id);
$vendor_detail = Vendor_detail::select('vendor_id','province')->where('vendor_id',$id)->get()->toArray();
$data= array_merge($vendor,$vendor_detail);
I think you should use database join to get faster results.
$vendor = Vendor::join('vendor_details', 'vendors.id', '=', 'vendor_details.vendor_id')
->select('vendors.*', 'vendor_name','vendor_value')
->where('id', $id)
->first();
if ($vendor) {
$vendor = $vendor->toArray();
}
$vendor_detail = Vendor_detail::where('vendor_id',$id)->get(); will give you a collection
as well as $plucked = $vendor_detail->pluck('vendor_name','vendor_value'); will give you a collection, so, either you can use collection merge or you may like to loop through one and add merge another as other answer is doing, but these are not array, you are getting collections.
Hi I have an array that contains two arrays that has the following structure:
categories [
"lvl0" => array:2 [
0 => "Cleaning"
1 => "Bread"
]
"lvl1" => array:2 [
0 => null
1 => "Bread > rolls"
]
]
I would like to remove any records of NULL from the 'lvl1' array but have not been able to find the correct method to do this.
I have tried:
array_filter($categories['lvl1'])
But this also removes all records associated to lvl1 and not just the NULL ones.
Any help would be greatly appreciated.
Thanks
array_filter() takes a callback as the second argument. If you don't provide it, it returns only records that aren't equal to boolean false. You can provide a simple callback that removes empty values.
array_filter() also uses a copy of your array (rather than a reference), so you need to use the return value.
For instance:
$categories = [
"lvl0" => [
"Cleaning",
"Bread"
],
"lvl1" => [
null,
"Bread > rolls"
]
];
$lvl1 = array_filter($categories['lvl1'], function($value) {
return !empty($value);
});
var_dump($lvl1);
That will return:
array(1) {
[1] =>
string(13) "Bread > rolls"
}
I was having the same issue on my last working day.Generally for associative array array_filter() needs the array key to filter out null, false etc values. But this small function help me to filter out NULL values without knowing the associative array key. Hope this will also help you, https://eval.in/881229
Code:
function array_filter_recursive($input)
{
foreach ($input as &$value)
{
if (is_array($value))
{
$value = array_filter_recursive($value);
}
}
return array_filter($input);
}
$categories = [
"lvl0" => [
"Cleaning",
"Bread"
],
"lvl1" => [
null,
"Bread > rolls"
]
];
$result = array_filter_recursive($categories);
print '<pre>';
print_r($result);
print '</pre>';
Output:
(
[lvl0] => Array
(
[0] => Cleaning
[1] => Bread
)
[lvl1] => Array
(
[1] => Bread > rolls
)
)
Ref: http://php.net/manual/en/function.array-filter.php#87581
Robbie Averill who commented on my post with the following solved the issue:
$categories['lvl1'] = array_filter($categories['lvl1']);
I have a family tree app in laravel, and I want to be able to show an outline view (start with a family from long ago, show its kids, show those kids' families, those families' kids, etc).
So I made this recursive get_descendants function:
public static function get_descendants(Family $family, $results_array, $counter)
{
// start new round with a different temp array, to keep track
$counter++;
$this_array = "array_$counter";
$$this_array = [];
array_push ($$this_array, $family->caption);
$kids = FamilyController::get_kids_of_family($family);
// if family has no kids, return 0;
if (!count($kids))
{
return 0;
}
else // add kids and check for their families
{
foreach ($kids as $kid) {
array_push ($$this_array, $kid->firstname);
// get families made by kid- for each one, call get_descendants
$families_made = FamilyController::get_families_person_made($kid);
foreach ($families_made as $new_family) {
array_push($$this_array, self::get_descendants($new_family, $$this_array, $counter));
}
};
// we've gone through the kids, add this round's array to the general results array
array_push ($results_array, $$this_array);
}
return $results_array;
}
I've confirmed with print statements that the looping through is correct, but there's a problem with the way I'm saving the results. I want to get something like this, where the top family shows once, with children and their families nested:
array:1 [▼
0 => array:4 [▼
0 => "Padme & Anakin"
1 => "Leia"
2 => array:3 [▼
0 => "Leia & Han"
1 => "Kylo Ren"
]
3 => "Luke"
]
]
but I'm getting this (with an extra repeat in the middle):
array:1 [▼
0 => array:4 [▼
0 => "Padme & Anakin"
1 => "Leia"
2 => array:3 [▼
0 => "Padme & Anakin"
1 => "Leia"
2 => array:3 [▼
0 => "Leia & Han"
1 => "Kylo Ren"
]
]
3 => "Luke"
]
]
Can anyone see where my mistake is?
Update: it turns out that it works if I get rid of that final results_array and just use the dynamic one the whole way, like this:
public static function get_descendants(Family $family, $results_array, $counter)
{
// start new round with a different temp array, to keep track
$counter++;
$this_array = "array_$counter";
$$this_array = [];
array_push ($$this_array, $family->caption);
$kids = FamilyController::get_kids_of_family($family);
// if family has no kids, return 0;
if (!count($kids))
{
return 0;
}
else // add kids and check for their families
{
foreach ($kids as $kid) {
array_push ($$this_array, $kid->first);
// get families made by kid- for each one, call get_descendants
$families_made = FamilyController::get_families_person_made($kid);
if (count($families_made))
{
foreach ($families_made as $new_family) {
array_push($$this_array, self::get_descendants($new_family, $$this_array, $counter));
}
}
};
}
return $$this_array;
}
Looks unnecessarily complex, with dynamic arrays, and you keep populating the same array, so that's why Luke appears in the wrong place.
A cleaner solution might be to be very specific about where people are in the array rather than using a dynamic array name. Just a suggestion -
public static function getDescendants(Family $family)
{
$family = [];
$family['name'] = $family->caption;
if ($kids = static::getKidsOfFamily($family)) {
foreach ($kids as $kid) {
$family['children'][] = $kid->firstname;
$subfamilies = static::getFamiliesPersonMade($kid);
foreach ($subfamilies as $subfamily) {
$family['subfamilies'][] = static::getDescendants($subfamily);
}
};
}
return $family;
}
would produce something like
array [
"name" => "Padme & Anakin"
"children" => array [
"Leia",
"Luke"
],
"subfamilies" => array [
array [
"name" => "Leia & Han"
"children" => array [
"Kylo Re"
]
]
]
]
I am very new to PHP, learning fast but not fast enough! I am also learning Laravel 5.1.
I am trying to build a HTML select list array from an Eloquent query output, in the correct format for form builder (Form::select).
I have the following call to Eloquent to pull the data:
// Get list of States for address select
$states = State::all()->toArray();
It returns the following array:
array:8 [▼
0 => array:2 [▼
"id" => "1"
"state" => "ACT"
]
1 => array:2 [▼
"id" => "2"
"state" => "NSW"
]
...
];
I want to loop through it and generate the following output:
array = [
'' => 'State', <-- This is the default for the select list
'1' => 'ACT',
'2' => 'NSW',
...
];
I am using Laravel 5.1, so I am using the included array_add() function in my helper.
I call my function like this:
$states = create_select_list($states, 'State');
I next want to format the output so it is ready for the Form::select statement. I have tried the code below (as the final try from a few iterations!) but unsuccessfully.
function create_select_list($data, $default)
{
// Declare array and set up default select item
$container = ['' => $default];
// Loop through data entries and build select list array
foreach($data as list($entry, list($key, $value))) {
$container = array_add($container, $key, $value);
}
// Return the select list array
return $container;
}
All help or suggestions are appreciated!
This answer is not about loop fix. I think previous comment should help you.
Just another idea. You can try use array_map instead foreach for this case.
For example:
$states = ['' => 'State'];
array_map(function($item) use (&$states) {
$states[$item['id']] = $item['state'];
}, State::all()->toArray());
Loop like below:
foreach($data as $key => $keyArr ) {
$container = array_add($container, $keyArr['id'], $keyArr['state']);
}
You don't need to use list() in your foreach loop, instead try:
foreach($data as $key => $value) {
$container = array_add($container, $key, $value);
}
The PHP documentation gives a good overview of what list() actually does.