【问题标题】:Differentiate associated array from regular array将关联数组与常规数组区分开来
【发布时间】:2010-08-12 19:46:29
【问题描述】:

无需更改函数签名,如果给定关联数组而不是常规数组,我希望 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 可以做到这一点吗?

【问题讨论】:

  • 此函数如何处理包含数字和关联索引混合的数组 (array(1, 2, 'foo' => 'bar', 3, 4, 'hello' => 'world'))?
  • 假设数组是同质的;没有混合物。

标签: php arrays associative-array


【解决方案1】:

只需检查任意键的类型:

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

【讨论】:

  • 我最喜欢这种方法。谢谢:)
【解决方案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;
}

请注意,这将相当慢,因为它涉及迭代,但它应该更节省内存,因为它不需要复制任何数组。

编辑:考虑到您的同质要求,您可以简单地这样做:

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

但请注意,数字是关联数组的有效键。我假设您正在谈论一个带有字符串键的关联数组(这是上面的 if 将处理的内容)...

【讨论】:

  • 关于您的编辑。您可以拥有一个没有键 0 的数字数组,例如array(1 =&gt; null)
  • 那么它在技术上不是一个数组,它仍然是一个哈希表(因此是一个关联数组)。数组只会有从 0 到最大的连续数字索引...
【解决方案3】:

假设 $foo 是同构的,只需检查 one 键的类型即可。

<?php

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

?>

【讨论】:

    【解决方案4】:

    根据您的评论Assume arrays are homogenous; no mixtures.: 只需检查第一个(或最后一个,或随机)键是整数还是字符串。

    【讨论】:

      【解决方案5】:

      这是一种方法,通过检查是否有任何由非数字值组成的键:

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

      【讨论】:

        【解决方案6】:
        function is_associative($array) {
          return count(array_keys($array)) != array_filter(array_keys($array), 'is_numeric');
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-02
          • 2012-01-21
          • 2011-09-06
          • 1970-01-01
          相关资源
          最近更新 更多