Laravel - Carry array through map - php

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.

Related

how to make an eloquent result into an array Laravel

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();

Cannot access collection by properties Laravel 5.8

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')

Laravel relationship query where using array

I'm trying to return all the attributes from my database that have a set foreign key (Attribute groups). I've set up all the relationships in my model but I'm unsure how to query these relationships using a collection or array.
AttributeGroup -
public function attribute()
{
return $this->hasMany('App\Attribute', 'group_id');
}
Attribute -
public function attributeGroup()
{
return $this->belongsTo('App\AttributeGroup');
}
My current query -
$page = Page::where('slug', $slug)->firstOrFail();
$groups = AttributeGroup::where('page_id', $page->id)->get()->toArray();
$atts = Attribute::where('group_id', $groups[0]['id'])->get();
This works because we have set the specific index of the array using $groups[0]
Is there a simple way I can pass an array through to the query using their relationships or is looping through the results and then passing my own array to the query the best approach?
$attributes = array();
foreach ($groups as $group){
array_push($attributes, $group['id']);
}
$atts = Attribute::where('group_id', $attributes)->get();
$groups is a collection. Assume them as arrays on steroids. Therefore you can use the pluck() method to get those ids you need:
$page = Page::where('slug', $slug)->firstOrFail();
$groups = AttributeGroup::where('page_id', $page->id)->get();
$atts = Attribute::where('group_id', $groups->pluck('id'))->get();
Also if you've set your relationships correctly, you should be able to loop through $groups and access the attributes of those $groups. You can test it:
$groups = AttributeGroup::where('page_id', $page->id)->get();
dd($groups->first()->attributes);

Cast Laravel Collection into array

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;
}

Eloquent column list by key with array as values?

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();
});

Categories