Как найти значение в массиве с определенной структурой,


Точные определения положения одного массива в другой, в следующей структуре:

array{
  [0]=>{
    ["id"]=>"5744"
    ["fk"]=>"7"
    ["nome"]=>"Nivel 1"
    ["created"]=>"2014-04-30 16:54:14"
    ["modified"]=>NULL
    ["user_created"]=>NULL
    ["sadmin"]=>"N"
    ["color"]=>NULL
  }
  [1]=>{
    ["id"]=>"5745"
    ["fk"]=>"5744,7"
    ["nome"]=>"Nível 2"
    ["created"]=>"2014-04-30 16:56:21"
    ["modified"]=>NULL
    ["user_created"]=>NULL
    ["sadmin"]=>"N"
    ["color"]=>NULL
  }
  [2]=>{
    ["id"]=>"5746"
    ["fk"]=>"5745,5744,7"
    ["nome"]=>"Nível 3"
    ["created"]=>"2014-04-30 16:57:15"
    ["modified"]=>NULL
    ["user_created"]=>NULL
    ["sadmin"]=>"N"
    ["color"]=>NULL
  }
}

в Качестве примера: у меня есть значение - 5746, и я должен сделать поиск через него, то есть, мне нужно все, что находится в положении 2 массива.

Я для редактирования добавление важной информации, что я просто не упоминаю:

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

 12
Author: Kenny Rafael, 2014-04-30

6 answers

Очень интересно, много ответов, в том числе ответы на голосование, указания решения-код гипса, которые фильтруют массив только один экземпляр, вручную закодированные в одном лишь условно.

... Мое предложение похоже на данной друга @Cahe, но она гораздо компактнее и убивает проблемы с точностью снайпера и, в придачу, еще, если она стоит больше ресурсов, современных языка: Iterator.

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

/**
 * Searches value inside a multidimensional array, returning its index
 *
 * Original function by "giulio provasi" (link below)
 *
 * @param mixed|array $haystack
 *   The haystack to search
 *
 * @param mixed $needle
 *   The needle we are looking for
 *
 * @param mixed|optional $index
 *   Allow to define a specific index where the data will be searched
 *
 * @return integer|string
 *   If given needle can be found in given haystack, its index will
 *   be returned. Otherwise, -1 will
 *
 * @see http://www.php.net/manual/en/function.array-search.php#97645
*/
function search( $haystack, $needle, $index = NULL ) {

    if( is_null( $haystack ) ) {
        return -1;
    }

    $arrayIterator = new \RecursiveArrayIterator( $haystack );

    $iterator = new \RecursiveIteratorIterator( $arrayIterator );

    while( $iterator -> valid() ) {

        if( ( ( isset( $index ) and ( $iterator -> key() == $index ) ) or
            ( ! isset( $index ) ) ) and ( $iterator -> current() == $needle ) ) {

            return $arrayIterator -> key();
        }

        $iterator -> next();
    }

    return -1;
}

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

var_dump( search( $valores, '5745,5744,7' ) ); // Saída int(2)

Дополнительно у нас есть третий аргумент, который позволяет ограничить поиск до одного конкретного расположения индекс матрица.

Пример использования сразу выше будет выглядеть так:

var_dump( search( $valores, '5745,5744,7', 'fk' ) );

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

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

var_dump( $valores[ search( $valores, '5745,5744,7', 'fk' ) ] );

Следите только, что в данном примере курсов учитывает значение реальной и существующей. В реальном приложении, где значение, если поиск не может существовать, должно быть сделано проверка случае, если функция возвращает -1, учитывая, что, очевидно,, -1 это не допустимый индекс для массива, даже если это, неправильно, действительны для PHP.

 5
Author: Bruno Augusto, 2014-11-07 09:53:38

Я Не опытный php, но, думаю, что это может помочь.

Предполагая, что массив ввода-это то, что вы прошли назван $valores:

$valores = array(
  0 => array(
    "id" =>"5744",
    "fk" =>"7",
    "nome" =>"Nivel 1",
    "created" =>"2014-04-30 16:54:14",
    "modified" =>NULL,
    "user_created" =>NULL,
    "sadmin" =>"N",
    "color" =>NULL),

  1 => array(
    "id"=>"5745",
    "fk"=>"5744,7",
    "nome"=>"Nível 2",
    "created"=>"2014-04-30 16:56:21",
    "modified"=>NULL,
    "user_created"=>NULL,
    "sadmin"=>"N",
    "color"=>NULL),

  2 => array(
    "id"=>"5746",
    "fk"=>"5745,5744,7",
    "nome"=>"Nível 3",
    "created"=>"2014-04-30 16:57:15",
    "modified"=>NULL,
    "user_created"=>NULL,
    "sadmin"=>"N",
    "color"=>NULL)
);

И, чтобы получить ИДЕНТИФИКАТОР, вы можете использовать простой for:

// Busca pelo elemento de ID 5746

foreach ($valores as &$valor) 
{
    if($valor["id"] == "5746")
    {
        // Array encontrado.
        print_r($valor);
    }
}
 7
Author: Lucas Lima, 2014-04-30 21:11:57

, Если вам нужно найти значение 5746 независимого ключа вы можете сделать:

foreach ($array as $key => $val){
  if (in_array("5746", $val)){
     $find = $val;
  }
}
print_r($find);

, Или, если вам нужно найти значение 5746 для ключа id, вы можете сделать;

foreach ($array as $key => $val){
  if ($val['id'] == 5746){
     $find = $val;
  }
}
print_r($find);

Вариант также будет использовать callback функция array_filter():

$array = array_filter($array, function($ar) { return ($ar['id'] == '5746'); });
 4
Author: abfurlan, 2014-04-30 22:08:12

То Же, что вопрос, на котором частично решить, я оставлю пример альтернативной реализации функции array_search, где вы можете "фильтровать", членом массива определенные значения:

function array_match($needle, $haystack, $strict = TRUE)
{
    foreach($haystack as $key => $member) {
        if(is_array($member) === FALSE)
            continue; // procuramos somente em arrays
        $tomatch = count($needle); // quantos valores precisam ser iguais
        $matches = 0;
        foreach($needle as $nkey => $nvalue) {
            if(isset($member[$nkey]) === FALSE)
                break; // a sub-array não possui o valor
            if($strict === TRUE) {
                if($member[$nkey] === $nvalue)
                    $matches++;
                else
                    break; // o valor é diferente do que queremos
            } else {
                if($member[$nkey] == $nvalue)
                    $matches++;
                else
                    break; // o valor é diferente do que queremos
            }
        }
        if($tomatch == $matches)
            return $key; // encontramos
    }
    return NULL;
}

Например:

$needle = array(
    "id"=>"5746",
    "nome"=>"Nível 3",
    "sadmin"=>"N"
);
echo array_match($needle, $data); // "2"

Приведенный выше код возвращает индекс ($data, который имеет те же элементы и значения $needle, дополнительно вы можете сказать, если сравнивать значения должны быть в строгом (===) - или-не.

 3
Author: Cahe, 2014-04-30 22:20:38

Начиная с PHP 5.5.0, новую функцию array_column() можно упростить сценарии, которые обычно используем.

print_r( array_search( '5746', array_column( $array, 'id' ) ) );

См. руководство: http://php.net/array_column

 2
Author: Daniel Omine, 2014-05-13 18:39:35
    function busca($valores, $id){
        foreach($valores as $key => $value){
            if ($value['id'] == $id){
                return $value;
            }
        }
        return null;
    }

    var_dump(busca($valores, "5746"));
 1
Author: , 2014-04-30 21:30:23