简体   繁体   English

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

[英]Get all values from nested array in PHP?

For this nested array: 对于此嵌套数组:

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

I want to know if a certain value "ERROR" exists at least once in the array. 我想知道某个值“ ERROR”在数组中是否至少存在一次。 I don't care what key it's associated with, I just want to know if the $status array contains an "ERROR" status anywhere in it. 我不在乎它与什么键相关联,我只想知道$ status数组是否在其中任何位置包含“ ERROR”状态。

Is there a cleaner way to do this than just iterating over the elements with nested for loops? 除了遍历嵌套for循环的元素之外,还有没有更干净的方法可以做到这一点?

You could use the function array_walk_recursive() to get all the values with any level of nested array. 您可以使用函数array_walk_recursive()来获取任何级别的嵌套数组的所有值。

https://secure.php.net/manual/en/function.array-walk-recursive.php 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>';
?>

Output: 输出:

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

I actually wouldn't use array recursive. 我实际上不会使用数组递归。 It falls short in a few key things you want to do. 它缺少您要执行的一些关键操作。 And while at first it may seem like a "shortcut" to what you want,if fails in a few key ways: 乍一看,它看起来像是您想要的“捷径”,但如果通过以下几个关键方式失败:

  • you can't return a simple testable value like a boolean true of false from the callback in it. 您无法从其中的回调返回简单的可测试值,例如布尔true值为false。
  • you can't build the $all array with nesting, because the keys that have an array as their value are never passed to the callback. 您不能使用嵌套构建$all数组,因为以数组为键值的键永远不会传递给回调。 This essentially flattens the array out. 这实质上使阵列变平。
  • it's not portable, or in other words it's not reusable as it's procedural in nature. 它不是可移植的,换句话说,它本质上是过程性的,因此不可重用。

That said, honestly I wouldn't build the all array because it's pointless as you already have that array, so there is no point copying it. 就是说,老实说,我不会构建all数组,因为它已经没有意义,因为您已经拥有该数组,因此没有意义复制它。 As I said I don't think you really want to rebuild $all but if you did you couldn't do it with array_walk_recursive even if you wanted to... 正如我说的那样,我认为您并不是真的要重建$all但是即使您这样做,即使您愿意,也无法使用array_walk_recursive完成它。

Anyway. 无论如何。

$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";

prints 版画

true
true
false

Test it 测试一下

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

UPDATE I see you changed the question and while you say "value" your array says the "key" 更新我看到你改变了问题,当你说“值”时,你的数组说“键”

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

Because all the values are the same. 因为所有值都相同。 So if you really want to find the key instead then just change it to this 因此,如果您确实要查找密钥,则只需将其更改为此

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

A few things to note when checking for the keys, it's possible they will not always be strings, or that you will check using an unqoted number. 检查密钥时需要注意的几件事,有可能它们不一定总是字符串,或者您将使用不带编号的数字进行检查。 In these cases PHP sometimes has a weird way of changing a string into an integer and non-numeric strings will come out as 0 . 在这些情况下,PHP有时会采用一种怪异的方式将字符串更改为整数,而非数字字符串将显示为0 For example "1" = 1 but "one" = 0 when taken as an integer. 例如, "1" = 1但当取整数时"one" = 0 Therefore if you have an array with a key of 0 and you check for one it will match it because it will turn "one" into a 0 . 因此,如果您有一个键为0的数组,并检查是否为one则它将与之匹配,因为它将"one"变为0

You can solve this by casting everything to strings. 您可以通过将所有内容强制转换为字符串来解决此问题。 Or by using the === strict type checking. 或通过使用===严格类型检查。 I prefer the string method because checking with === would make 0 != "0" so if you tried finding a key of 0 with "0" it would say no match. 我更喜欢使用字符串方法,因为使用===进行检查将使0 != "0"因此,如果尝试使用"0"查找键0 ,它将表示不匹配。 This is true of other numbers. 其他数字也是如此。 That is unless you plan on checking objects with it. 除非您打算使用它检查对象。

This is still an issue when looking for the "values" but it's less of one, because there you are not dealing with the native integer keys in an array, so there is a greater possibility you wouldn't encounter it. 在寻找“值”时,这仍然是一个问题,但要少得多,因为您没有处理数组中的本机整数键,因此您更可能不会遇到它。

It all has to do with PHP's loosely typed nature, it's a feature not a bug... 所有这些都与PHP的松散类型性质有关,这是一个功能,而不是bug。

I put this small example togather: 我把这个小例子放在一起:

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");

Outputs: 输出:

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

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

cheers! 干杯!

:-p :-p

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM