从PHP中的嵌套数组中获取所有值?

时间:2018-04-23 15:48:17

标签: php

对于这个嵌套数组:

$status = array(
  "house" => "OK",
  "car" => array(
      "car1" => "OK",
      "car2" => "ERROR"
   ),
   "boat" => "OK"
);

我想知道某个值是否有错误" ERROR"在数组中至少存在一次。我不在乎它与之关联的关键字,我只想知道$ status数组是否包含" ERROR"状态中的任何地方。

有没有比使用嵌套for循环遍历元素更简洁的方法呢?

2 个答案:

答案 0 :(得分:4)

您可以使用函数array_walk_recursive()来获取任何级别的嵌套数组的所有值。

https://secure.php.net/manual/en/function.array-walk-recursive.php

<?php
$status = array(
    "house" => "OK",
    "car" => array(
        "car1" => "OK",
        "car2" => "OK"
    ),
    "boat" => "OK"
);

$required = array();
array_walk_recursive($status, function ($value, $key) use (&$required){
    $required[] = $value;
}, $required);
print '<pre>';
print_r($required);
print '</pre>';
?>

<强>输出:

Array
(
    [0] => OK
    [1] => OK
    [2] => OK
    [3] => OK
)

答案 1 :(得分:2)

我实际上不会使用数组递归。它缺少你想要做的几件关键事情。虽然起初它可能看起来像一个&#34;捷径&#34;如果你想要什么,如果以几个关键方式失败:

  • 你不能从回调函数中返回一个简单的可测试值,如布尔值为true。
  • 您无法使用嵌套构建$all数组,因为具有数组作为其值的键永远不会传递给回调。这基本上使阵列变平。
  • 它不是便携式的,换句话说,它不具有可重用性,因为它本质上是程序性的。

那说,说实话,我不会构建all数组,因为它已经没有了,因为你已经有了这个数组,所以没有必要复制它。正如我所说,我不认为你真的想要重建$all,但如果你这样做,即使你想要array_walk_recursive,也无法做到这一点。

反正。

$array = ['zero','one', 'two' => ['zoo' => 'foo']];


function checkRecursive($value, $array){  
    $x = false;
    foreach($array as $v){

        if(is_array($v)) $x = checkRecursive($value, $v); //recursive

        if($v == $value || $x == true) return true;
    }
    return false;
}


echo checkRecursive('one', $array) ? "true\n" : "false\n";
echo checkRecursive('foo', $array) ? "true\n" : "false\n";  
echo checkRecursive('bar', $array) ? "true\n" : "false\n";

打印

true
true
false

测试

http://sandbox.onlinephpfunctions.com/code/78d0de421475b8e3104376c698027107e9b7e948

<强>更新 我看到你改变了问题,而你说&#34;价值&#34;你的数组说&#34;键&#34;

$status = array(
  "house" => "OK",
  "car" => array(
      "car1" => "OK",
      "car2" => "OK"
   ),
   "boat" => "OK"
);

因为所有值都相同。因此,如果您真的想要找到密钥,那么只需将其更改为此

即可
function checkRecursive($value, $array){  
    $x = false;
    foreach($array as $k=>$v){
        if(is_array($v)) $x = checkRecursive($value, $v); //recursive
        if((string)$value == (string)$k || $x == true) return true;
    }
    return false;
}

在检查密钥时需要注意的一些事项,它们可能不会总是字符串,或者您将使用未分配的数字进行检查。在这些情况下,PHP有时会有一种将字符串更改为整数的奇怪方法,非数字字符串将以0形式出现。例如"1" = 1,但"one" = 0作为整数。因此,如果您的数组的密钥为0且检查one,则会匹配它,因为它会将"one"变为0

您可以通过将所有内容转换为字符串来解决此问题。或者使用===严格类型检查。我更喜欢字符串方法,因为使用===进行检查会产生0 != "0"因此,如果您尝试使用0找到"0"的密钥,则表示不匹配。其他数字也是如此。除非你打算用它来检查对象,否则就是这样。

在寻找&#34;值时,这仍然是一个问题。但它不是一个,因为你没有处理数组中的原生整数键,所以你更有可能遇到它。

这一切都与PHP的松散类型有关,它不是一个错误的功能...

我把这个小例子收集起来:

echo '(int)"one": ';
echo (int)"one";
echo "\n";
echo "0 == 'one': " . (0 == "one" ? "true\n" : "false\n");
echo "1 == '1': " . (1 == "1" ? "true\n" : "false\n");

输出:

(int)"one": 0
0 == 'one': true
1 == '1': true

http://sandbox.onlinephpfunctions.com/code/df41f55251570a12d9ca693712bcdc785ad62f85

喝彩!

: - P