Intereting Posts
включить отключить выбор / выпадающий выбор радио Zend Framework – последний код для выполнения перед компоновкой Создание анонимных функций из PHP 5.3 работает с PHP 5.2 Каковы преимущества / недостатки монолитного кодирования PHP по сравнению с небольшими специализированными скриптами php? PHP / HTML Добавить кнопку удаления дата и мили, когда более 100, в противном случае возвращают красный светофор Ошибка «Class HTML not found» в Laravel 4 Элегантный способ получить количество месяцев между двумя датами? Как подсчитать div определенного класса с помощью PHP DOMDocument Подготовленный оператор не позволяет мне называть $ mysqli-> stmt_init () PHP перезагрузить чат-бокс? Отправка электронной почты с помощью вложения через PHPMailer создание динамической строки mysql? json, возвращаемый с php, не может быть проанализирован для jQuery dataTables XML-файл – получить определенные дочерние узлы в неограниченных глубинах узлов

PHP Поиск массива для нескольких пар ключ / значение

У меня есть список массивов (для этого примера я использую сотовые телефоны). Я хочу, чтобы иметь возможность искать несколько пар ключ / значение и возвращать его индекс родительского массива.

Например, вот мой массив:

// $list_of_phones (array) Array ( [0] => Array ( [Manufacturer] => Apple [Model] => iPhone 3G 8GB [Carrier] => AT&T ) [1] => Array ( [Manufacturer] => Motorola [Model] => Droid X2 [Carrier] => Verizon ) ) 

Я хочу иметь возможность сделать что-то вроде следующего:

 // This is not a real function, just used for example purposes $phone_id = multi_array_search( array('Manufacturer' => 'Motorola', 'Model' => 'Droid X2'), $list_of_phones ); // $phone_id should return '1', as this is the index of the result. 

Любые идеи или предложения о том, как я могу или должен это делать?

Solutions Collecting From Web of "PHP Поиск массива для нескольких пар ключ / значение"

Возможно, это будет полезно:

  /** * Multi-array search * * @param array $array * @param array $search * @return array */ function multi_array_search($array, $search) { // Create the result array $result = array(); // Iterate over each array element foreach ($array as $key => $value) { // Iterate over each search condition foreach ($search as $k => $v) { // If the array element does not meet the search condition then continue to the next element if (!isset($value[$k]) || $value[$k] != $v) { continue 2; } } // Add the array element's key to the result array $result[] = $key; } // Return the result array return $result; } // Output the result print_r(multi_array_search($list_of_phones, array())); // Array ( [0] => 0 [1] => 1 ) // Output the result print_r(multi_array_search($list_of_phones, array('Manufacturer' => 'Apple'))); // Array ( [0] => 0 ) // Output the result print_r(multi_array_search($list_of_phones, array('Manufacturer' => 'Apple', 'Model' => 'iPhone 6'))); // Array ( ) 

Как показывает вывод, эта функция возвращает массив всех ключей с элементами, которые соответствуют всем критериям поиска.

вы можете использовать array_intersect_key и array_intersect и array_search

check array_intersect_key php manual, чтобы получить массив элементов с соответствующими ключами

и array_intesect php manual для получения массива, если элементы с соответствующими значениями

u может получить значение ключа в массиве, используя $array[key]

и получить ключ значения в массиве, используя array_search $key = array_search('green', $array);

php.net/manual/en/function.array-search.php

Я закончил делать следующее. Это некрасиво, но работает очень хорошо. Для тех, кто читает, не стесняйтесь обновлять с помощью DRYer ответа:

 // Variables for this example $carrier = 'Verizon'; $model = 'Droid X2'; $manufacturer = 'Motorola'; // The foreach loop goes through each key/value of $list_of_phones and checks // if the given value is found in that particular array. If it is, it then checks // a second parameter (model), and so on. foreach ($list_of_phones as $key => $object) { if ( array_search($carrier, $object) ) { if ( array_search($model, $object) ) { if ( array_search($manufacturer, $object) ) { // Return the phone from the $list_of_phones array $phone = $list_of_phones[$key]; } } } } 

Работает как шарм.

Этот способ работает для многомерного массива, такого как ваш:

 $test = array_intersect_key($list_of_phones, array(array("Manufacturer" => "Motorola", "Carrier" => "Verizon"))); 

Я расширил код MichaelRushton, добавив поддержку для разных операторов сравнения:

 function multi_array_search ($array, $search) { $result = []; foreach ($array as $key => $value) { //iterate over each array element foreach ($search as $k => $v) { //iterate over each search condition $operator = $v[0]; $searchField = $v[1]; $searchVal = $v[2]; switch ($operator) { case '=': $cond = ($value[$searchField] != $searchVal); break; case '!=': $cond = ($value[$searchField] == $searchVal); break; case '>': $cond = ($value[$searchField] <= $searchVal); break; case '<': $cond = ($value[$searchField] >= $searchVal); break; case '>=': $cond = ($value[$searchField] < $searchVal); break; case '<=': $cond = ($value[$searchField] > $searchVal); break; } //if the array element does not meet the search condition then continue to the next element if ((!isset($value[$searchField]) && $value[$searchField] !== null) || $cond) { continue 2; } } $result[] = $key; //add the array element's key to the result array } return $result; } //incoming data: $phonesList = [ 0 => [ 'Manufacturer' => 'Apple', 'Model' => 'iPhone 3G 8GB', 'Carrier' => 'AT&T', 'Cost' => 100000 ], 1 => [ 'Manufacturer' => 'Motorola', 'Model' => 'Droid X2', 'Carrier' => 'Verizon', 'Cost' => 120000 ], 2 => [ 'Manufacturer' => 'Motorola', 'Model' => 'Droid X2', 'Carrier' => 'Verizon', 'Cost' => 150000 ] ]; var_dump(multi_array_search($phonesList, [ ['=', 'Manufacturer', 'Motorola'], ['>', 'Cost', '130000'] ] )); //output: array(1) { [0]=> int(2) } 

Это то же самое, что и @Boolean_Type, но немного улучшило ситуацию.

 function multi_array_search($array, $search) { $result = array(); foreach ($array as $key => $val) { foreach ($search as $k => $v) { // We check if the $k has an operator. $operator = '='; if (preg_match('(<|<=|>|>=|!=|=)', $k, $m) === 1) { // We change the operator. $operator = $m[0]; // We trim $k to remove white spaces before and after. $k = trim(str_replace($m[0], '', $k)); } switch ($operator) { case '=': $cond = ($val[$k] != $v); break; case '!=': $cond = ($val[$k] == $v); break; case '>': $cond = ($val[$k] <= $v); break; case '<': $cond = ($val[$k] >= $v); break; case '>=': $cond = ($val[$k] < $sv); break; case '<=': $cond = ($val[$k] > $sv); break; } if (( ! isset($val[$k]) && $val[$k] !== null) OR $cond) { continue 2; } } $result[] = $key; } return $result; } 

Таким образом, вы можете просто выполнить поиск следующим образом:

 $keys = multi_array_search($phonesList, array( 'Manufacturer' => 'Motorola', 'Cost >' => '130000', )); 

Если найдено, у вас будет и массив таких индексов: array(1, 25, 33) (Это только пример).