Is there a way to filter a collection returned by database query on Laravel?
Returned collection is this
1 => Person {#310 ▼
#table: "person"
#attributes: array:15 [▼
"name" => "Jon Doe"
"timeavailable" => "1,2,3,4,5,6,7,8"
2 => Person {#310 ▼
#table: "person"
#attributes: array:15 [▼
"name" => "Jon Moe"
"timeavailable" => "1,2,5,7,8"
Here, I want to filter the timeavailable attribute. I only want to show results for 1,2,3 . Is there a way to filter this collection so that I only get something like this
1 => Person {#310 ▼
#table: "person"
#attributes: array:15 [▼
"name" => "Jon Doe"
"timeavailable" => "1,2,3"
2 => Person {#310 ▼
#table: "person"
#attributes: array:15 [▼
"name" => "Jon Moe"
"timeavailable" => "1,2"
So, the filtered collection will have only 1,2,3 inclusions.
I think this is not the best solution, but it can be a way to solve for this problem. Check if this helps...
Try to use the map of Collection. In the inner function, you can explode, intersect and explode timeavailable.
$limiter = [1,2,3];
$filtered = $array->map(function($person, $k) use ($limiter) {
$ex = explode(',', $person->timeavailable);
$intersect = array_intersect($limiter, $ex);
$person->timeavailable = implode(",",$intersect);
return $person;
});
This will work fine for small results, but if you are planning to run this with lots of results, it will be slow.
Related
I have a deployments Laravel Collection like this:
Illuminate\Support\Collection {#415 ▼
#items: array:5 [▼
0 => array:7 [▼
"id" => 31
"status" => "active"
"name" => "Deployment 1"
"spots" => array:4 [▼
0 => array:2 [▼
"id" => 33
"status" => "active" <-- Want to change this
]
1 => array:2 [▶]
2 => array:2 [▶]
3 => array:2 [▶]
]
"data" => array:3 [▶]
]
1 => array:7 [▶]
2 => array:7 [▶]
3 => array:7 [▶]
4 => array:7 [▶]
]
}
I want to update the nested status value to inactive. I have used the Laravel map function, but it only seems to work on collections that have one nesting level. So this...
$this->deployments->map(function ($deployment) {
$deployment['spots'][0]['status'] = 'inactive';
});
dd($this->deployments);
...leaves $this->deployments untouched.
Also tried using nested map functions obtaining a Call to a member function map() on array exception on second level as second and next nesting levels are considered arrays...
Any thoughts?
Thanks in advance.
With the map method, you are almost there. You will have to return the change made in $deployment and do an ->all() at the end to update the collection with the modified values.
For updating a single spot:
$deployments = $deployments->map(function($deployment){
$deployment['spots'][0]['status'] = 'inactive';
return $deployment;
})->all();
For updating all spots:
$deployments = $deployments->map(function($deployment){
foreach($deployment['spots'] as &$spot){
$spot['status'] = 'inactive';
}
return $deployment;
})->all();
For anyone researching this, a more elegant solution might be:
For updating a single spot:
$data = $deployments->all();
$deployments = data_set($data, 'spots.0.status', 'inactive');
For updating all spots:
$data = $deployments->all();
$deployments = data_set($data, 'spots.*.status', 'inactive');
I have Project and Country Model. There is a many to many relations. I get projects with countries. Result is below
array:5 [▼
0 => array:5 [▼
"id" => 2
"account_id" => 1
"start_date" => "Jul 2012"
"end_date" => "Aug 2013"
"countries" => array:1 [▼
0 => array:2 [▼
"id" => 148
"pivot" => array:2 [▶]
]
]
]
1 => array:5 [▶]
2 => array:5 [▶]
3 => array:5 [▶]
4 => array:5 [▶]
]
I wont to get all unique countries count. In the now I do it with this way
$projects->pluck('countries')->collapse()->pluck('id')->unique()->count()
Question. Can I use pluck with nested relation column and has any more shortly and good solution?? for example like this
$projects->pluck('countries.id')->count();
You can use this:
$projects->pluck('countries.*.id')->flatten()->unique()->count()
You can't use:
$projects->pluck('countries.id')...
Because countries is an array of arrays.
But you can use the 'countries.*.id' on those cases
Or the other way round...
Country::whereHas('projects', function ($query) {
// $query->where(); if you want to limit the projects
})->count();
You get unique countries since your fetching from the countries table
I find this solution
$projects->groupBy('countries.*.id')->count();
I have this code where I try to grab all auth user categories:
$cats = Auth::user()->cats()->lists('title','id');
and I want to add new data to $cats so I write:
$cats->push(['5','BMW']);
but I got:
Collection {#459 ▼
#items: array:2 [▼
9 => "asd"
10 => array:2 [▼
0 => "5"
1 => "BMW"
]
]
}
How I to change my code to get this result:
Collection {#459 ▼
#items: array:2 [▼
9 => "asd"
5 => "BMW"
]
}
So how I can add the array to this collection?
p.s. I need this format because I use select2 jquery plugin
You can use the collection like an array:
$cats[5] = 'BMW';
I have the following Eloquent query in a Laravel 5.2 project:
$regsByCtryCollection = Organisation::join('countries_currencies', 'countries_currencies.id', '=', 'organisations.country_id')
->select(DB::raw('DISTINCT LCASE(countries_currencies.country_code) AS ctry, COUNT(organisations.id) AS val'))
->groupBy('ctry')
->get();
The raw query produces this output:
ctry val
at 1
au 5
br 1
The Eloquent call produces a collection of three rows (matching raw query output) like this:
Collection {#791 ▼
#items: array:3 [▼
0 => Organisation {#777 ▼
#table: "organisations"
#hidden: []
........
#attributes: array:2 [▶]
#original: array:2 [▼
"ctry" => "at"
"val" => 1
]
#relations: array:5 [▶]
........
}
1 => Organisation {#778 ▶}
2 => Organisation {#779 ▶}
]
}
I then pluck the values and format for Highmaps like this
$regsByCtry = $regsByCtryCollection->pluck('ctry', 'val')->map(function($country, $value) {
return [
"hc-key" => $country,
"value" => $value
];
})->values()->toJson();
And one of the values is dropped and I get this:
[
{"hc-key":"br","value":1},
{"hc-key":"au","value":5}
]
Why is the first entry getting dropped?
{"hc-key":"at","value":1}
I am using this same process with two other Eloquent queries and it works as expected, but just not on this collection.
Additionally, I also sum all the values in the array of objects like this:
$regsTotal = array_sum($regsByCtryCollection->pluck('val')->toArray());
And I get the correct value, including all three records summed:
$regsTotal = 7;
The issue is with pluck('ctry', 'val'). This will return val as key & ctry as value. In your query output at & br has same value 1. So one of it getting replaced by the other one.
Try pluck('val', 'ctry')->map(function($value, $country)
Reference
I am trying to get data in from multidimensional array without using foreach
i tried using in_array() function but not worked
$abc = array()
in_array($abc , $private_job->cities)
in_array() expects parameter 2 to be array, string given
on using $private_job->cities got the following result
Collection {#408 ▼
#items: array:2 [▼
0 => city {#416 ▼
+wasRecentlyCreated: false
#attributes: array:2 [▼
"id" => 7
"city_name" => "Gujranwala"
]
}
1 => city {#417 ▼
+wasRecentlyCreated: false
#attributes: array:2 [▶]
#original: array:4 [▼
"id" => 4
"city_name" => "Islamabad"
"pivot_private_jobabd_id" => 53
"pivot_city_id" => 4
]
}
]
}
whereas i am interested in getting
"id" => 7
"id" => 4
in an an array
$result = $private_job->cities->map(function($data){
return $data['id'];
})->all();