2010-08-12 1 views
3

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

Примечание: Вы можете предположить, что массивы являются однородными. Например, array(1,2,"foo" => "bar") не принимается и может быть проигнорирован.

function my_func(Array $foo){ 
    if (…) { 
    echo "Found associated array"; 
    } 
    else { 
    echo "Found regular array"; 
    } 
} 


my_func(array("foo" => "bar", "hello" => "world")); 
# => "Found associated array" 

my_func(array(1,2,3,4)); 
# => "Found regular array" 

Возможно ли это с помощью PHP?

+1

Как бы эту функцию лечить массивы, которые содержат смесь числовых и ассоциативных индексов ('массив (1, 2, 'Foo' => 'бар', 3, 4, 'Привет' => 'мир') ')? – BoltClock

+0

Предположим, что массивы однородны; без смесей. –

ответ

6

Просто проверьте тип любой клавиши:

function is_associative(array $a) { 
    return is_string(key($a)); 
} 

$a = array(1 => 0); 
$a2 = array("a" => 0); 

var_dump(is_associative($a)); //false 
var_dump(is_associative($a2)); //true 
+0

Мне нравится этот метод лучше всего. Благодаря :) –

2

ВЫ МОЖЕТЕ использовать чек с array_values, если ваши массивы небольшие, и вам не нужны накладные расходы (если они большие, это будет довольно дорого, так как требует копирования всего массива только для проверки, а затем утилизации из него):

if ($array === array_values($array)) {} 

Если вы заботитесь о памяти, вы можете сделать:

function isAssociative(array $array) { 
    $c = count($array); 
    for ($i = 0; $i < $c; $i++) { 
     if (!isset($array[$i])) { 
      return true; 
     } 
    } 
    return false; 
} 

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

Edit: Учитывая ваше требование однородного, вы можете просто сделать это:

if (isset($array[0])) { 
    // Non-Associative 
} else { 
    // Associative 
} 

Но обратите внимание, что Числовые являются допустимыми ключами для ассоциативного массива. Я предполагаю, что вы говорите об ассоциативном массиве со строковыми клавишами (это то, что указано выше, если будет обрабатываться).

+0

Относительно вашего редактирования. Вы можете иметь числовой массив, который не имеет ключа '0', например. 'array (1 => null)' – Artefacto

+0

Тогда это не технически массив, это все еще хэш-таблица (и, следовательно, ассоциативный массив). Массивы будут иметь только последовательные числовые индексы от 0 до max ... – ircmaxell

0

В свете вашего комментария Assume arrays are homogenous; no mixtures.: Просто проверьте, первым ли (или последним или случайным) key - целое число или строка.

0

Это будет один из способов сделать это, проверяя, есть ли какие-либо ключи, состоящие из нечисловых значений:

function my_func($arr) { 
    $keys = array_keys($arr); // pull out all the keys into a new array 
    $non_numeric = preg_grep('/\D/', $keys); // find any keys containing non-digits 
    if (count($non_numeric) > 0) { 
     return TRUE; // at least one non-numeric key, so it's not a "straight" array 
    } else { 
     return FALSE: // all keys are numeric, so most likely a straight array 
    } 
} 
2

Допуская $foo является однородным, просто проверьте тип один ключ и все.

<?php 

function my_func(array $foo) { 
    if (!is_int(key($foo))) { 
     echo 'Found associative array'; 
    } else { 
     echo 'Found indexed array'; 
    } 
} 

?> 
0
function is_associative($array) { 
    return count(array_keys($array)) != array_filter(array_keys($array), 'is_numeric'); 
}