Reputation: 3647
Given the following 2D array:
$data_info_array = array(
array(
'score' => '100',
'name' => 'Alice',
'subject' => 'Data Structures'
),
array(
'score' => '50',
'name' => 'Bob',
'subject' => 'Advanced Algorithms'
),
array(
'score' => '75',
'name' => 'Charlie',
'subject' => 'Distributed Computing'
)
);
// this gets the key when I search for the score of 50 from one column
$index = array_search('50', array_column($data_info_array, 'score'));
echo $index;
If I want to search by two values I can only think of something like:
$index1 = array_search('50', array_column($data_info_array, 'score'));
$index2 = array_search('Bob', array_column($data_info_array, 'name'));
$real_index = ( $index1 === $index2 ) ? $index1 : null;
Is there a way I can search for score of '50' and name of 'Bob' together and get the index to that only if that combo exists? Is there a better way do do than what I've come up with?
Upvotes: 3
Views: 4955
Reputation: 89557
You can build your search query as an array and compare the intersection of each item with it.
$search = ['score' => '50', 'name' => 'Bob'];
foreach($data_info_array as $k => $v) {
if ( $search === array_intersect($v, $search) ) {
echo $k;
break;
}
}
@mickmackusa noticed it is safer to use array_intersect_assoc()
here. He's right because when the multi-dimensional array items are unpredictable, nothing forbids to have items like that:
['miaou' => '50', 'graou' => 'Bob', 'score' => '50', 'name' => 'Bob']
where the searched values are also present but for other keys. In this case array_intersect()
returns all correct values (with their corresponding keys of course) regardless the keys in $search
, and the comparison with the search array will return false
.
But using array_intersect_assoc()
, you ensure that only values for keys in $search
are taken in account.
Conclusion: If you let yourself be lulled into sleep by the seeming monotony of multidimensional array items, you won't be immune to surprise when unexpected variations arise.
Upvotes: 4
Reputation: 129
Here is a nice one-liner, utilizing PHP arrow functions
$name = "Alice";
$score = "100";
$result = array_filter($data_info_array, fn($data) => $data['name'] == $name && $data['score'] == $score );
print_r($result);
Upvotes: 2
Reputation: 57121
You can use array_filter()
, which allows you to do as many checks on the contents as you need at the same time...
$output = array_filter($data_info_array, function ($data) {
return $data['score'] == 50 && $data['name'] == 'Bob';
});
This will give you a list of the matches, so you may need to do [0]
(and check if only 1 is returned) if you need a single match.
Upvotes: 6