Определение ассциативности массива, php

Вопрос довольно простой, но с решением туговато.
Есть два массива:
array('a','b','c');
array('x'=>'a','y'=>'b','z'=>'c');

Нужно определелить, является ли массив ассоциативным или нет. Первый массив идентичен
array(0=>'a',1=>'b',2=>'c');
Первое, что приходит в голову — это взять array_keys() от массива и проверить последний ключ на соответствие значению sizeof($array) — 1. Такое решение довольно просто, но может работать с ошибками. Итерироваться по ключам нет никакого желания. Поэтому решил написать сюда. Есть варианты попроще и побыстрее?
  • Вопрос задан
  • 7776 просмотров
Решения вопроса 1
shushu
@shushu
$a = array(1,3,5,"c"=>5);
var_dump( range( 0, count($a) -1 ) == array_keys( $a ) );


Работает довольно шустро, Только память употребляет хорошо :)
зы: я бы не стал использовать на массивах с больше чем 100к елементов…
Ответ написан
Пригласить эксперта
Ответы на вопрос 9
Aux
@Aux
В PHP не бывает не ассоциативных массивов. Поэтому только проход.
Ответ написан
MisterX
@MisterX
Неплохой вариант сделан в Kohana,
/**
* Tests if an array is associative or not.
*
* @param array array to check
* @return boolean
*/
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;
}
Ответ написан
Комментировать
Hast
@Hast
А что есть ассоциативный массив? у массива ключи могут быть как индексные так и ассоциативные. Если нужно, чтобы все ключи были ассоциативными, то как-нибудь так:

$assoc = true;
foreach ($array as $key => $element)
{
if (is_numeric($key)) $assoc = false;
break;
}
Ответ написан
conf
@conf
Ruby developer
Простите, а зачем вам это нужно?
Ответ написан
каким образом вы хотите отлавливать массивы вида
array(0=>'a', 1=>'b', 'c'=> 'd', 3=>'e');

без прохода по всем массиву?

Проход по всему массиву будет в любом случае, иначе это никак не проверить (если только у вас нет в проекте 100% уверенности в том что если «последний ключ соответвует значению sizeof($array) — 1» то массив «не ассоциативный»)
Ответ написан
grigruss
@grigruss
Пока не задал ни одного вопроса... только отвечаю.
Может кому пригодится:
if(is_numeric(array_search($a[0], $a))){
    echo "Не ассоциативный";
}else{
    echo "Ассоциативный";
}
Ответ написан
Комментировать
@eugen81
Программист PHP, JS
А если так?
function is_assoc(array $array) {
    return !empty(preg_grep('/[^0-9]/', array_keys($array)));
}
Ответ написан
Комментировать
Traineratwot
@Traineratwot
Web - программист
вот вариант который более точный чем проверка только первого ключа но не такой прожорливый как проверка всех ключей
function isAssoc(&$arr = []): bool
		{
			$c = count($arr);
			if ($c > 10) {
				return !(array_key_exists(0, $arr) and array_key_exists(random_int(0, $c - 1), $arr));
			} elseif ($c > 0) {
				return !(range( 0, count($arr) -1 ) == array_keys( $arr ));
			}
			return FALSE;
		}
Ответ написан
Комментировать
Lastor
@Lastor
В чем сила, брат? В ньютонах.
В php 8.1 появилась встроенная функция array_is_list()
Примеры

array_is_list([]); // true
array_is_list(['apple', 2, 3]); // true
array_is_list([0 => 'apple', 'orange']); // true

// Массив начинается не с 0
array_is_list([1 => 'apple', 'orange']); // false

// Ключи массива не по порядку
array_is_list([1 => 'apple', 0 => 'orange']); // false

// Ключи массива не являются целыми числами
array_is_list([0 => 'apple', 'foo' => 'bar']); // false

// Непоследовательные ключи
array_is_list([0 => 'apple', 2 => 'bar']); // false

Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы