Хобрук: Ваш путь к мастерству в программировании

Как искать многомерный массив по нескольким значениям сразу в PHP?

Учитывая следующий 2D-массив:

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

Если я хочу выполнить поиск по двум значениям, я могу думать только о чем-то вроде:

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

Есть ли способ, которым я могу искать счет «50» и имя «Боб» вместе и получить индекс для этого, только если эта комбинация существует? Есть ли лучший способ сделать, чем то, что я придумал?


Ответы:


1

Вы можете построить свой поисковый запрос в виде массива и сравнить с ним пересечение каждого элемента.

$search = ['score' => '50', 'name' => 'Bob'];

foreach($data_info_array as $k => $v) {
    if ( $search === array_intersect($v, $search) ) {
        echo $k;
        break;
    }
}

@micmackusa заметил, что здесь безопаснее использовать array_intersect_assoc(). Он прав, потому что, когда элементы многомерного массива непредсказуемы, ничто не запрещает иметь такие элементы:

['miaou' => '50', 'graou' => 'Bob', 'score' => '50', 'name' => 'Bob']

где искомые значения также присутствуют, но для других ключей. В этом случае array_intersect() возвращает все правильные значения (конечно, с соответствующими ключами) независимо от ключей в $search, а сравнение с массивом поиска возвращает false.

Но используя array_intersect_assoc(), вы гарантируете, что учитываются только значения ключей в $search.

Вывод: если вы позволите себе уснуть из-за кажущегося однообразия элементов многомерного массива, вы не застрахованы от сюрприз при появлении непредвиденных изменений.

05.03.2020
  • Безопаснее использовать array_intersect_assoc($search, $v), верно, @Cas? 28.03.2021
  • @micmackusa: вы также можете использовать array_intersect_assoc(), но не уверены, что получите что-то более производительное или более безопасное, потому что в порядке сравнение решает, присутствует ли элемент или нет, и без правильных ключей сравнение возвращает false независимо от значений на пересечении. 29.03.2021
  • @micmackusa: Но я понимаю, что вы имеете в виду, такой инопланетный предмет: array_intersect(['50', 'Bob', 'score'=>'50', 'name'=>'Bob'],['score' => '50', 'name' => 'Bob']). 29.03.2021

  • 2

    Вы можете использовать array_filter(), что позволяет одновременно выполнять столько проверок содержимого, сколько вам нужно...

    $output = array_filter($data_info_array, function ($data) {
        return $data['score'] == 50 && $data['name'] == 'Bob';
    });
    

    Это даст вам список совпадений, поэтому вам может потребоваться выполнить [0] (и проверить, возвращается ли только 1), если вам нужно одно совпадение.

    05.03.2020

    3

    Вот хороший однострочный, использующий функции стрелок PHP

    $name = "Alice";
    $score = "100";
    
    $result = array_filter($data_info_array, fn($data) => $data['name'] == $name && $data['score'] == $score );
    
    print_r($result);
    
    05.03.2020
    Новые материалы

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..

    Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
    Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

    Расширенные методы безопасности для VueJS: реализация аутентификации без пароля
    Руководство, которое поможет вам создавать безопасные приложения в долгосрочной перспективе Безопасность приложений часто упускается из виду в процессе разработки, потому что основная..

    стройный-i18следующий
    Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..

    Обзор 20 основных и современных методов работы с массивами в JavaScript
    Вы знаете их всех? В этом коротком посте я покажу сводку методов, доступных в JavaScript для работы с массивами. Я надеюсь, что вы найдете это полезным! В конце поста вы найдете ссылку на..

    Да, но я чувствую необходимость указать, что это или не единственные два.
    Да, но я чувствую необходимость указать, что это или не единственные два. Обучение с подкреплением (в качестве примера) также является важным.