So I can do this with Eloquent:
$roles = DB::table('roles')->lists('title', 'name');
But is there a way to make Eloquent fetch an array of values for each distinct key instead of just one column?
For instance, something like the following:
$roles = DB::table('roles')->lists(['*', DB:raw('COALESCE(value, default_value)')], 'name');
You can use the keyBy method:
$roles = Role::all()->keyBy('name');
If you're not using Eloquent, you can create a collection on your own:
$roles = collect(DB::table('roles')->get())->keyBy('name');
If you're using Laravel 5.3+, the query builder now actually returns a collection, so there's no need to manually wrap it in a collection again:
$roles = DB::table('roles')->get()->keyBy('name');
If you need a key/value array, since Laravel 5.1 you can use pluck. This way you can indicate which attributes you want to use as a value and as a key.
$plucked = MyModel::all()->pluck(
'MyNameAttribute',
'MyIDAttribute'
);
return $plucked->all();
You will get an array as follow:
array:3 [▼
1 => "My MyNameAttribute value"
2 => "Lalalala"
3 => "Oh!"
]
You may try something like this:
$roles = array();
array_map(function($item) use (&$roles) {
$roles[$item->id] = (Array)$item; // object to array
}, DB::table('roles')->get());
If you want to get an Object instead of an Array as value then just remove the (Array).
Alternative: Using Eloquent model (Instead of DB::table):
$roles = array();
array_map(function($item) use (&$roles) {
$roles[$item['id']] = $item;
}, Role::all()->toArray());
Another Alternative: Using Collection::map() method:
$roles = array();
Role::all()->map(function($item) use(&$roles) {
$roles[$item->id] = $item->toArray();
});
Related
I want to combine two data search results into one array, I use array_merge but there is an array_merge() error:
Argument # 1 is not an array
How to turn $vendor's eloquent results into an array and combine it with $plucked?
$vendor = Vendor::find($id);
$vendor_detail = VendorDetail::where('vendor_id',$id)->get();
$plucked = $vendor_detail->pluck('vendor_profile_value','vendor_profile_name');
$coba = array_merge($vendor,$plucked);
$plucked already an array
I think the problem here is that $vendor is not yet an array
You could do it like this:
$vendor = Vendor::find($id);
$vendor_details = VendorDetail
::select('vendor_profile_value', 'vendor_profile_name')
->where('vendor_id', $id)
->get()
->toArray();
$coba = array_merge($vendor,$vendor_details);
The get() method execute the query returning a Collection instance, in which you can call the toArray() method.
Side note
As far as I can see, you could make use of relationships and eager loading.
If you have a one-to-many relationship defined like this in your Vendor model:
public function details()
{
return $this->hasMany(VendorDetails::class);
}
Then, you could eager load the relationship like this:
$vendor = Vendor::with('details')->find($id);
// ^^^^^^^^^^^^^^
You could even just load the wanted fields:
$vendor = Vendor::with('details:vendor_profile_value,vendor_profile_name')
->find($id);
Then, your object will have a new attribute called "details" containing the related objects (or a collection of the limited selected fields).
You can convert the $vendor to an Array like below.
$vendor = Vendor::find($id)->toArray();
So I have three different arrays with the same length in the request and below is how I combine them into one collection:
$inputs = collect();
$keys = collect(['id', 'username', 'email']);
foreach ($request['ids'] as $index => $id) {
$username = $request['usernames'][$index];
$email = $request['emails'][$index];
$inputs->push($keys->combine([$id, $username, $email]));
}
The result looks correct to me:
However, I cannot access the collection when I iterate over it:
foreach ($inputs as $input) {
dd($input->id); // Property [id] does not exist on this collection instance.
}
This is the result of dd($input):
Any pointers on this problem? (Another short way to combine the arrays into one collection will also be appreciated!)
Thank you.
It is a collection and you should get it like this: dd($input['id']).
You can combine arrays bt array_merge
array_merge($a1,$a2)
or collect
$c=collect([$arr1,$arr2])
then pluck if you want
$c->pluck('username')
Let's say I have a model collection that I'm mapping through like this:
$alreadyImported = [];
$players = Players::whereNotIn('id', $alreadyImported)
->get()
->random(25)
->pluck('id');
$groups = $players->map(function ($item, $key) use ($alreadyImported) {
array_merge($alreadyImported, $item->id);
$group = [
'username' => $item['username'],
];
return $group;
});
// $groups is a pivot table with group and players
Why does my $globalList always start at []? How can I carry the already-merged $globalList to the next map iteration?
The player IDs does not matter. It's for show. I am looking to pass the array through the map iterations.
Just use pluck() to get IDs from the collection:
$ids = $players->pluck('id');
Or, if you just need IDs:
$ids = Players::where('banned', false)->pluck('id');
If you're going to add any other data, you don't need to merge it to some array or a collection because map() will create a new collection.
Finally, you don't need to use collect() because get() will return collection.
I am trying to refactor my code, and remove a for loop.
$result = [];
foreach ($data as $language) {
$result[$language->{$key}] = $language->{$column};
}
This became:
$result = $data->map(function($language) use ($key, $column){
return [$language->{$key} => $language->{$column}];
});
But now instead of:
[
"key":"value",
"key":"value"
]
I am getting
[
{
"key":"value"
},
{
"key":"value"
}
]
Why doesn't it map like an array?
Please refer this URL
For Example:
$emailLookup = $employees->reduce(function ($emailLookup, $employee) {
$emailLookup[$employee['email']] = $employee['name'];
return $emailLookup;
}, []);
Gives you result like:
const emailLookup = {
'john#example.com': 'John',
'jane#example.com': 'Jane',
'dave#example.com': 'Dave',
};
In your case do like:
$result = $data->reduce(function($language, $a){
$language[$a['any_you_want']] = $a['any_you_want'];
return $language;
}, []);
Hope this helps you!
You probably needed to mapWithKeys:
$result = $data->mapWithKeys(function($language) use ($key, $column){
return [$language->{$key} => $language->{$column}];
});
The method has been available since Laravel 5.3
According to the docs:
The mapWithKeys method iterates through the collection and passes each value to the given callback. The callback should return an associative array containing a single key / value pair:
For your simple use case, pluck() is the method you're looking for. It will build a new collection using one column of an existing array. You can also pass in a second field that will be used to key the new collection.
So, in your case, the data column you're selecting is $column, and the column to use as the key for the new collection is $key. Your code would be:
$result = $data->pluck($column, $key);
This says "give me a collection of all of the $column data, and key it by the $key data".
If you want the plain array instead of the collection, just call all() on the result:
$result = $data->pluck($column, $key)->all();
If you need to "pluck" more than one column of data, you will need to use the mapWithKeys() method already mentioned.
Here in loop you need to use as key value pair
$result = [];
foreach ($data as $key => $language) {
$result[$key] = $language;
}
Here is my code$titles = DB::table('roles')->lists('title');
How Can I cast $titles from a Laravel 5 collection into an associative array?
Include the ID in the function, and call from the Model:
$titles = Role::lists('title', 'id')->toArray();
Or call directly as you are doing:
$titles = DB::table('roles')->lists('title', 'id');
In this case, in an select field for example, the id will be the option value.
A laravel collection has a toArray method that will return a numerically keyed array of the contents. (The indexes will be keyed exactly as they are in the collection. To reset them call values on the collection first.)
$titles = DB::table('roles')->lists('title');
$result = $titles->toArray();
For an associative array you will need to do this manually using something like this.
$titles = DB::table('roles')->lists('title', 'id');
$result = [];
foreach($titles as $title) {
// using an ID as the key and title as the value
$result[$title->id] = $title->title;
}