Я хотел бы иметь возможность передать массив функции, и функция будет вести себя по-разному в зависимости от того, массив массивов «списка» или массив «хэш». Например:
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")))
Вытащил прямо из рамки коханы.
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 (eg the keys array looked like {0:0, 1:1...}). return array_keys($keys) !== $keys; }
Этот тест дает 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; }
PHP обрабатывает все массивы как хэши, технически, поэтому нет точного способа сделать это. Лучше всего будет следующее:
if (array_keys($array) === range(0, count($array) - 1)) { //it is a hash }
Нет, 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) }
(выше для форматирования для удобочитаемости)
Мое решение состоит в том, чтобы получить ключи массива, как показано ниже, и проверить, что если ключ не является целым числом:
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" )
Таким образом, это не очень хорошая идея, чтобы сравнить его с целым рядом чисел, как указано в рейтинге. Он всегда будет говорить, что это хэш-массив, если вы попытаетесь сравнить ключи с диапазоном.