Определите, является ли массив ассоциативным (хэш) или нет

Я хотел бы передать массив функции и функция будет вести себя по-разному в зависимости от того, массив массивов "списка" или массив "хэш". Например:.

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

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

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

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

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

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

Ответ 1

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

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;
}

Ответ 2

Этот тест дает 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;
}

Ответ 3

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

if (array_keys($array) === range(0, count($array) - 1)) {
   //it is a hash
}

Ответ 4

Нет, 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)
}

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

Ответ 5

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

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"
)

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