Reputation: 431
I need to get all "top level" keys from multidimensional array by searching the "bottom level" values. Here is an example of the array:
$list = array (
'person1' => array(
'personal_id' => '1',
'short_information' => 'string',
'books_on_hand' => array(
'Book 1',
'Book 2',
'Book 3',
)
),
'person2' => array(
'personal_id' => '2',
'short_information' => 'string',
'books_on_hand' => array(
'Book 4',
'Book 2',
'Book 5',
)
),
'person3' => array(
'personal_id' => '3',
'short_information' => 'string',
'books_on_hand' => array(
'Book 4',
'Book 2',
'Book 1',
'Book 3',
)
),
//etc...
);
I want to know all persons who have "Book 2" on hand. I can get that information by loop like this:
foreach ($list as $person => $info){
$check = array_search( 'Book 2', array_column($info, 'books_on_hand') );
if ( $check !== false ){
$results .= 'Name: '.$person;
$results .= 'ID: '.$info['personal_id'];
//get other infos other stuff, if necessary
}
}
The problem is, that foreach
in this case is very heavy on memory and only grows more when array has a thousand+ entries. It needs to run through all of the persons, even if only 3 persons at the very top of the array have "Book 2".
I have been trying to optimize it by getting persons with "Book 2" using built-in functions like array_search
, array_keys
, array_column
and only then run foreach
for persons found, but I had no luck with getting "top level" keys.
Is it possible to optimize or use built-in function to search multidimensional array?
Upvotes: 1
Views: 81
Reputation: 78994
One way would be to filter it first. Now your result is structured like $list
but it only contains elements with the needed book:
$find = 'Book 2';
$result = array_filter($list, function($v) use($find) {
return in_array($find, $v['books_on_hand']);
});
If all you're interested in is the person key and personal_id
then this:
$find = 'Book 2';
$result = array_map(function($v) use($find) {
if(in_array($find, $v['books_on_hand'])) {
return $v['personal_id'];
}
}, $list);
Will return something like this for persons with the needed book:
Array
(
[person1] => 1
[person2] => 2
[person3] => 3
)
Upvotes: 1