开发者

Differentiate associated array from regular array

Without having to change the function signature, I'd like a PHP function to behave differently if given an associated array instead of a regular array.

Note: You can assume arrays are homogenous. E.g., array(1,2,"foo" => "bar") is not accepted and can be ignored.

function my_func(Array $foo){
  if (…) {
    echo "Found associated array";
  }
  else {
    echo "Found regular arr开发者_如何转开发ay";
  }
}


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

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

Is this possible with PHP?


Just check the type of any key:

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


You COULD use a check with array_values if your arrays are small and you don't care about the overhead (if they are large, this will be quite expensive as it requires copying the entire array just for the check, then disposing of it):

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

If you care about memory, you could do:

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

Note that this will be fairly slow, since it involves iteration, but it should be much more memory efficient since it doesn't require any copying of the array.

Edit: Considering your homogenious requirement, you can simply do this:

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

But note that numerics are valid keys for an associative array. I assume you're talking about an associative array with string keys (which is what the above if will handle)...


Assuming $foo is homogeneous, just check the type of one key and that's it.

<?php

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

?>


In the light of your comment Assume arrays are homogenous; no mixtures.: Just check if first (or last, or random) key is an integer or a string.


This would be one way of doing it, by checking if there's any keys consisting of non-numeric values:

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


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜