Laravel `array_pluck` on any key - php

Is possible use something like array_pluck($array, 'users.*.id')?
Imagine that I have:
$array = [
'users' => [
[ 'id' => 1 ],
[ 'id' => 2 ],
[ 'id' => 3 ],
]
];
And I want get [1, 2, 3].
I tried something like: users.*.id, users.id and users..id, but nothing worked.

From Laravel 5.7, you may use the Arr::pluck() helper.
use Illuminate\Support\Arr;
Arr::pluck($array['users'], 'id')
Use array_pluck($array['users'], 'id')
The function only supports a single dimensional array. It will search for keys in the array which match the second parameter; which in your case is 'id'. You'll note that the array you're searching in your examples only has a key named users and none with the name id.
Using $array['users'] means pluck looks through that array and subsequently finds keys named id on each element.

You can use Laravel collections to achieve something like this.
$data = collect($array['users']);
$ids = $data->pluck('id');
return $ids;

you should use https://laravel.com/docs/5.7/helpers#method-array-pluck.
Don't recreate helpers that already exist ;)

Related

How to get the values of a multi-dimensional array by key in Laravel?

Let's say for example you have a constant multi-dimensional array with multiple keys (and values), but you want to filter out specific keys with it's values. See a example array below:
const defaultInvestmentFields = [
[
'type' => 'system',
'investment_name' => 'Ballast'
],
[
'type' => 'system',
'investment_name' => 'Inverters'
],
[
'type' => 'system',
'investment_name' => 'Extra garantie inverters'
]
];
The output I want is an array with only the values of investment_name. Like ['Ballast', 'Inverters', 'Extra garantie inverters'].
Additionally to #Levi's answer, you can use an array helper to avoid having to transform the array into a collection and back: Arr::pluck()
Arr::pluck(Project::defaultInvestmentFields, 'investment_name');
A quick and neat solution would be to use the collect wrapper function which is provided by Laravel. After that we can use the pluck function in order to specify which values by their key(s) we want to get. For example:
collect(Project::defaultInvestmentFields)->pluck('investment_name');
Now we have a Collection of the following values: Ballast, Inverters and Extra garantie inverters.
In order to use it as an array, simply call toArray() on it.

Check if values in array are in another array using Laravel Validation

I want to check if all the values of my input, an array, are in another array. For example:
$my_arr = ['item1', 'item2', 'item3', 'item4'];
Validator::make($request, [
'item' => [ /* what do i put here??? */ ],
]);
I don't think the rule in works, because that expects a single value as input, not an array. in_array doesn't work either. I've tried creating a custom rule or closure, but neither of those allow me to pass in a parameter (the array I want to check against). Especially since I want this same functionality for multiple arrays, for different inputs, it would be nice to have a generic rule that works for any array I give it.
If that's not possible, I suppose I need to create a rule for each specific array and use !array_diff($search_this, $all) as this answer says. Is there an alternative to this?
True that in doesn't accept an array but a string. So you can just convert the array into a string.
$my_arr = ['item1', 'item2', 'item3', 'item4'];
Validator::make($request, [
'item' => [ 'in:' . implode(',', $my_arr) ],
]);
implode
Another better solution might be to use Illuminate\Validation\Rule's in method that accepts an array:
'item' => [ Rule::in($my_arr) ],
Laravel Validation - Rule::in

Laravel - How to makeHidden multidimensional?

There is a multidimensional array. I want to makeHidden the children of the array:
Model::with('someRelation')->get()->toArray();
what I get is:
array [
'something',
'something_else',
'something2' => [
'something_inside_something2_to_be_visible' => 'someValue',
'something_inside_something2_to_be_hidden' => 'someValue2',
]
]
what I want to get is the array without something_inside_something2 inside something2. Something like this:
Model::with('someRelation')->get()->makeHidden(['something.something_inside_something2'])->toArray();
How can I do that?
If i understood what you mean, you need keys only.
you can do something like this:
$user = User::first();
dd(array_keys($user->toArray()));
Well I think you want to load just some columns from the relationship. In that case tell explicitly what you need from the relationship in with method.
Model::with('someRelation:primary_key,another_column,more_column')->get()->toArray();

(Laravel 5.3) How to add new key and value to existing sub array in existing Collection?

I am using Laravel 5.3.
existing Collection $a is
$a = collect(
[
0 =>[
'firstName' => 'John',
'lastName' => 'Doe'
],
1 =>[
'firstName' => 'Mary',
'lastName' => 'Jane'
]
]);
and desired result is as below:
$a = collect(
[
0 => [
'firstName' => 'John',
'lastName' => 'Doe',
'occupation' => 'engineer'
],
1 => [
'firstName' => 'Mary',
'lastName' => 'Jane',
'occupation' => 'accountant'
]
]);
I tried to test ->push(), ->put(), ->prepend() but no success. Please let me know the best way to do this.
You can use transform method which iterates over the collection and calls the given callback with each item in the collection. The items in the collection will be replaced by the values returned by the callback:
$a->transform(function ($item, $key) {
$item['occupation'] = 'some_value';
retrun $item;
});
Then check the value of $a:
dd($a);
Note that you have a collection of arrays, not a collection of collections. Hence, you can't use push(), put(), etc., in the sub-arrays.
The easiest way is probably just to treat it as an array:
$a[0]['occupation'] = 'engineer';
But you can also access at least the first element through the getter if you'd like:
$a->get(0)['occupation'] = 'engineer';
If you have an existing collection then you can get all the arrays from it using something like this:
$items = $existingCollection->all();
Now, you have an array of arrays in $items. So you can add key/value using something like this:
$item[0]['occupation'] = 'engineer';
$item[1]['occupation'] = 'accountant';
Now, you've modified the arrays so if you want to turn it back into a collection then you can do it easily using this:
$existingCollection = collect($items);
You could've also used map on the collection directly, for example:
$existingCollection->map(function ($person) {
$person['occupation'] = 'engineer';
return $person;
});
In this case, you can see that, all the person's occupation is going to be same but you can find out a way to make the difference but I can't give you more precise solution because I don't know much about your situation (You didn't share much).

How to make associative array in Yii2?

I would like to make associative array using foreach to use in Yii 2 dropdownlist.
My goal is to make array like following using foreach-
$array= [
['id' => '123', 'name' => 'abc'],
['id' => '124', 'name' => 'def'],
];
And then I want to use them using Yii 2 ArrayHelper::map().
$result = ArrayHelper::map($array, 'id', 'name');
How do I make the array using foreach?
Yii way to build items for drop-down list is exactly as you described, using ArrayHelper::map():
$items = ArrayHelper::map($array, 'id', 'name');
You don't need to use foreach here, just pass results of ActiveQuery as array:
$array = YourModel::find()->all();
Update:
Thanks. But here, I am actually calculating custom value for 'name'
and for that reason I want to use foreach to generate the array after
the calculation
You definetely need to add this information to the question, but anyway, you can use the ArrayHelper for that too. Take a look at toArray method. It can be used for both object / array of objects. After processing with this method you can use map.
Official docs:
ArrayHelper::map()
ArrayHelper::toArray()

Categories