3

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?

3 Answers 3

6

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.

Sign up to request clarification or add additional context in comments.

Comments

4

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.

4 Comments

Safer to use array_intersect_assoc($search, $v), right @Cas?
@mickmackusa: You can also use array_intersect_assoc() but not sure you obtain something more performant or safer, because in fine, the comparison decides if the item is present or not, and without the correct keys, the comparison returns false whatever the values in the intersection.
@mickmackusa: But I see what you mean, an alien item like that: array_intersect(['50', 'Bob', 'score'=>'50', 'name'=>'Bob'],['score' => '50', 'name' => 'Bob']).
Removing 'break;' will allow for all matches to be returned (if for example, there was a case where more than one item had a score of 50).
2

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.