PHP поиск многомерных массивов по значению - PullRequest
273 голосов
/ 12 июля 2011

У меня есть массив, в котором я хочу найти uid и получить ключ массива.

Примеры

Предположим, у нас есть следующий двумерный массив:

$userdb = array(
    array(
        'uid' => '100',
        'name' => 'Sandra Shush',
        'pic_square' => 'urlof100'
    ),
    array(
        'uid' => '5465',
        'name' => 'Stefanie Mcmohn',
        'pic_square' => 'urlof100'
    ),
    array(
        'uid' => '40489',
        'name' => 'Michael',
        'pic_square' => 'urlof40489'
    )
);

Вызов функции search_by_uid(100) (идентификатор первого пользователя) должен вернуть 0.

Вызов функции search_by_uid(40489) должен вернуть 2.

Я пыталсяделать циклы, но я хочу быстрее выполнить код.

Ответы [ 22 ]

401 голосов
/ 12 июля 2011
function searchForId($id, $array) {
   foreach ($array as $key => $val) {
       if ($val['uid'] === $id) {
           return $key;
       }
   }
   return null;
}

Это будет работать.Вы должны назвать это так:

$id = searchForId('100', $userdb);

Важно знать, что если вы используете оператор ===, сравниваемые типы должны быть точно такими же, в этом примере вы должны искать string или простоиспользуйте == вместо ===.

На основе angoru ответа.В более поздних версиях PHP (>= 5.5.0) вы можете использовать однострочник.

$key = array_search('100', array_column($userdb, 'uid'));

Вот документация: http://php.net/manual/en/function.array-column.php.

263 голосов
/ 02 июля 2014

Если вы используете (PHP 5> = 5.5.0), вам не нужно писать собственную функцию для этого, просто напишите эту строку, и все готово.

Если вам нужен только один результат:

$key = array_search(40489, array_column($userdb, 'uid'));

Для нескольких результатов

$keys = array_keys(array_column($userdb, 'uid'), 40489);

Если у вас есть ассоциативный массив, как указано в комментариях, вы можете сделать егос:

$keys = array_keys(array_combine(array_keys($userdb), array_column($userdb, 'uid')),40489);

Если вы используете PHP <5.5.0, вы можете использовать <a href="https://github.com/ramsey/array_column" rel="noreferrer"> этот бэкпорт , спасибо, ramsey!

Обновление: я делал некоторыепростые тесты и форма с несколькими результатами, кажется, самая быстрая, даже быстрее, чем пользовательская функция Jakub!

24 голосов
/ 12 июля 2013

Построение из превосходного ответа Якуба , вот более обобщенный поиск, который позволит указать ключ (не только для uid):

function searcharray($value, $key, $array) {
   foreach ($array as $k => $val) {
       if ($val[$key] == $value) {
           return $k;
       }
   }
   return null;
}

Использование: $results = searcharray('searchvalue', searchkey, $array);

18 голосов
/ 22 февраля 2013

Я знаю, что на этот вопрос уже был дан ответ, но я использовал его и немного расширил в своем коде, чтобы у вас не было поиска только по uid.Я просто хочу поделиться им с кем-то еще, кому могут понадобиться эти функции.

Вот мой пример, и, пожалуйста, помните, что это мой первый ответ.Я вынул массив param, потому что мне нужно было искать только один конкретный массив, но вы могли легко добавить его. Я хотел по сути искать больше, чем просто по uid.

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

 /**
     * @param array multidimensional 
     * @param string value to search for, ie a specific field name like name_first
     * @param string associative key to find it in, ie field_name
     * 
     * @return array keys.
     */
     function search_revisions($dataArray, $search_value, $key_to_search) {
        // This function will search the revisions for a certain value
        // related to the associative key you are looking for.
        $keys = array();
        foreach ($dataArray as $key => $cur_value) {
            if ($cur_value[$key_to_search] == $search_value) {
                $keys[] = $key;
            }
        }
        return $keys;
    }

Позже я написал это, чтобы позволить мне искать другое значение и ассоциативный ключ.Итак, мой первый пример позволяет вам искать значение в любом конкретном ассоциативном ключе и возвращать все совпадения.

Во втором примере показано, где в определенном ассоциативном ключе (first_name) найдено значение ('Тейлор') AND в другом ассоциативном ключе найдено другое значение (true) (используется)и возвращает все совпадения (ключи, в которых работают люди с именем «Тейлор» И).

/**
 * @param array multidimensional 
 * @param string $search_value The value to search for, ie a specific 'Taylor'
 * @param string $key_to_search The associative key to find it in, ie first_name
 * @param string $other_matching_key The associative key to find in the matches for employed
 * @param string $other_matching_value The value to find in that matching associative key, ie true
 * 
 * @return array keys, ie all the people with the first name 'Taylor' that are employed.
 */
 function search_revisions($dataArray, $search_value, $key_to_search, $other_matching_value = null, $other_matching_key = null) {
    // This function will search the revisions for a certain value
    // related to the associative key you are looking for.
    $keys = array();
    foreach ($dataArray as $key => $cur_value) {
        if ($cur_value[$key_to_search] == $search_value) {
            if (isset($other_matching_key) && isset($other_matching_value)) {
                if ($cur_value[$other_matching_key] == $other_matching_value) {
                    $keys[] = $key;
                }
            } else {
                // I must keep in mind that some searches may have multiple
                // matches and others would not, so leave it open with no continues.
                $keys[] = $key;
            }
        }
    }
    return $keys;
}

Использование функции

$data = array(
    array(
        'cust_group' => 6,
        'price' => 13.21,
        'price_qty' => 5
    ),
    array(
        'cust_group' => 8,
        'price' => 15.25,
        'price_qty' => 4
    ),
    array(
        'cust_group' => 8,
        'price' => 12.75,
        'price_qty' => 10
    )
);

$findKey = search_revisions($data,'8', 'cust_group', '10', 'price_qty');
print_r($findKey);

Результат

Array ( [0] => 2 ) 
17 голосов
/ 14 июня 2017

В более поздних версиях PHP (> = 5.5.0) вы можете использовать эту однострочную строку:

$key = array_search('100', array_column($userdb, 'uid'));
8 голосов
/ 25 января 2014

Я изменил один из приведенных ниже примеров функции array_search . Функция searchItemsByKey возвращает все значения по ключу $ из многомерного массива (N уровней). Возможно, это было бы полезно для кого-то. Пример:

 $arr = array(
     'XXX'=>array(
               'YYY'=> array(
                    'AAA'=> array(
                          'keyN' =>'value1'
                   )
               ),
              'ZZZ'=> array(
                    'BBB'=> array(
                          'keyN' => 'value2'
                   )
               )
              //.....
           )
);


$result = searchItemsByKey($arr,'keyN');

print '<pre>';
print_r($result);
print '<pre>';
// OUTPUT
Array
(
  [0] => value1
  [1] => value2
)

Код функции:

function searchItemsByKey($array, $key)
{
   $results = array();

  if (is_array($array))
  {
    if (isset($array[$key]) && key($array)==$key)
        $results[] = $array[$key];

    foreach ($array as $sub_array)
        $results = array_merge($results, searchItemsByKey($sub_array, $key));
  }

 return  $results;
}
5 голосов
/ 16 декабря 2016

выглядит array_filter будет подходящим решением для этого ...

$userdb=Array
(
    (0) => Array
        (
            (uid) => '100',
            (name) => 'Sandra Shush',
            (url) => 'urlof100'
        ),

    (1) => Array
        (
            (uid) => '5465',
            (name) => 'Stefanie Mcmohn',
            (pic_square) => 'urlof100'
        ),

    (2) => Array
        (
            (uid) => '40489',
            (name) => 'Michael',
            (pic_square) => 'urlof40489'
        )
);

PHP код

<?php 
$search = 5465;
$found = array_filter($userdb,function($v,$k) use ($search){
  return $v['uid'] => $search;
}) 

$values= print_r(array_value($found)); 
$keys =  print_r(array_keys($found)); 
3 голосов
/ 04 февраля 2015

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

function searchArrayKeyVal($sKey, $id, $array) {
   foreach ($array as $key => $val) {
       if ($val[$sKey] == $id) {
           return $key;
       }
   }
   return false;
}

Вместо этого вместо предустановленного uid указывается параметр в функции, поэтому теперь вызов приведенного ниже кода означает, что вы можете использовать одну функцию для нескольких типов массивов.Небольшое изменение, но имеющее небольшую разницу.

    // Array Data Of Users
$userdb = array (
    array ('uid' => '100','name' => 'Sandra Shush','url' => 'urlof100' ),
    array ('uid' => '5465','name' => 'Stefanie Mcmohn','url' => 'urlof100' ),
    array ('uid' => '40489','name' => 'Michael','url' => 'urlof40489' ),
);

// Obtain The Key Of The Array
$arrayKey = searchArrayKeyVal("uid", '100', $userdb);
if ($arrayKey!==false) {
    echo "Search Result: ", $userdb[$arrayKey]['name'];
} else {
    echo "Search Result can not be found";
}

Пример скрипта PHP

3 голосов
/ 22 декабря 2017

Вот один лайнер для того же,

$pic_square = $userdb[array_search($uid,array_column($userdb, 'uid'))]['pic_square'];
1 голос
/ 28 июля 2014
/**
 * searches a simple as well as multi dimension array
 * @param type $needle
 * @param type $haystack
 * @return boolean
 */
public static function in_array_multi($needle, $haystack){
    $needle = trim($needle);
    if(!is_array($haystack))
        return False;

    foreach($haystack as $key=>$value){
        if(is_array($value)){
            if(self::in_array_multi($needle, $value))
                return True;
            else
               self::in_array_multi($needle, $value);
        }
        else
        if(trim($value) === trim($needle)){//visibility fix//
            error_log("$value === $needle setting visibility to 1 hidden");
            return True;
        }
    }

    return False;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...