Определите, является ли массив ассоциативным (хэш) или нет - PullRequest
11 голосов
/ 13 мая 2011

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

myfunc(array("One", "Two", "Three")); // works
myfunc(array(1=>"One", 2=>"Two", 3=>"Three")); also works, but understands it's a hash

Может выводить что-то вроде:

One, Two, Three
1=One, 2=Two, 3=Three

то есть: функция делает что-то по-другому, когда она "обнаруживает", что ей передается хеш, а не массив. Можете ли вы сказать, что я пришел из Perl, где% хэши - это ссылки, отличные от @arrays?

Я считаю, что мой пример важен, потому что мы не можем просто проверить, является ли ключ числовым, потому что вы вполне можете использовать цифровые ключи в своем хеше.

Я специально стараюсь не использовать сложную конструкцию myfunc(array(array(1=>"One"), array(2=>"Two"), array(3=>"Three")))

Ответы [ 5 ]

38 голосов
/ 03 февраля 2013

Вытащил прямо из каркаса кохана.

public static function is_assoc(array $array)
{
    // Keys of the array
    $keys = array_keys($array);

    // If the array keys of the keys match the keys, then the array must
    // not be associative (e.g. the keys array looked like {0:0, 1:1...}).
    return array_keys($keys) !== $keys;
}
14 голосов
/ 04 марта 2015

Этот тест дает 3 метода.

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

1.Использование array_values ​​()

function($array) {
    return (array_values($array) !== $array);
}

2.Использование array_keys ()

function($array){
    $array = array_keys($array); return ($array !== array_keys($array));
}

3.Использование array_filter ()

function($array){
    return count(array_filter(array_keys($array), 'is_string')) > 0;
}
7 голосов
/ 13 мая 2011

Технически PHP обрабатывает все массивы как хеши, поэтому точного способа сделать это не существует.Я считаю, что лучшим вариантом будет следующее:

if (array_keys($array) === range(0, count($array) - 1)) {
   //it is a hash
}
0 голосов
/ 19 декабря 2011

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

private function is_hash($array) {
    foreach($array as $key => $value) {
        return ! is_int($key);
    }
    return false;
}

Неправильно получать array_keys массива хэшей, как показано ниже:

array_keys(array(
       "abc" => "gfb",
       "bdc" => "dbc"
       )
);

выведет:

array(
       0 => "abc",
       1 => "bdc"
)

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

0 голосов
/ 13 мая 2011

Нет, PHP не различает массивы, где ключи являются числовыми строками, от массивов, где ключи являются целыми числами, в следующих случаях:

$a = array("0"=>'a', "1"=>'b', "2"=>'c');
$b = array(0=>'a', 1=>'b', 2=>'c');

var_dump(array_keys($a), array_keys($b));

Вывод:

array(3) {
    [0]=> int(0) [1]=> int(1) [2]=> int(2)
}
array(3) {
    [0]=> int(0) [1]=> int(1) [2]=> int(2)
}

(выше отформатирован для удобства чтения)

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