如何通过多维数组的键递归搜索?

时间:2017-08-02 21:32:10

标签: php arrays json search recursion

我正在尝试创建一个递归函数,它接受一个数组并查找属性名children,并从匹配的数组中构造一个数组。

这不是直截了当的,因为我不知道哪个JSON数据块会包含密钥children,所以我决定写一个递归函数。

我试过

$testDataJson = '
{
    "macAddress": "10:20:30:40:50:81",
    "type": "HGW",
    "children": [{
        "macAddress": "98:D6:D6:D8:FF:34",
        "pendingMethods": false,
        "lastSeen": "2017-05-24T10:36:35",
        "lastSeenLight": "GREEN",
        "model": "AP7465CE-TN",
        "type": "WIRELESS_ACCESS_POINT"
    }, {
        "macAddress": "44:66:E9:A1:2C:DC",
        "pendingMethods": false,
        "lastSeen": "2017-05-24T10:39:01",
        "lastSeenLight": "GREEN",
        "model": "PLC 200+ DIV -TN",
        "type": "POWERLINE"
    }, {
        "macAddress": "D8:C2:A9:1C:44:47",
        "pendingMethods": "False",
        "lastSeen": "2017-05-24T10:39:01",
        "lastSeenLight": "GREEN",
        "model": "PG9073",
        "type": "POWERLINE",
        "children": [{
            "macAddress": "22:CD:E6:8F:8C:B8",
            "pendingMethods": false,
            "lastSeen": "2017-05-24T10:38:16",
            "lastSeenLight": "GREEN",
            "model": "PG9073",
            "type": "POWERLINE"
        }, {
            "macAddress": "13:E4:AB:33:36:AC",
            "pendingMethods": false,
            "lastSeen": "2017-05-24T10:29:13",
            "lastSeenLight": "GREEN",
            "model": "PG9072",
            "type": "POWERLINE_WIRELESS_ACCESS_POINT"
        }]
    }]
}';
$testDataArray = json_decode($testDataJson,true);

function recursiveKeyFinder($array) {
    $result = [];
    if (!isset($array['children']) AND is_array($array)) {
       return $result;
    }else {
        foreach($array['children'] as $child){
            $result['macAddress'] = $child['macAddress'];
        }
        return recursiveKeyFinder($array);
    }
}
var_dump(recursiveKeyFinder($testDataArray));

结果:var_dump()无效。

期望的结果:

["macAddress": "98:D6:D6:D8:FF:34",
"macAddress": "44:66:E9:A1:2C:DC",
"macAddress": "D8:C2:A9:1C:44:47",
"macAddress": "22:CD:E6:8F:8C:B8",
"macAddress": "13:E4:AB:33:36:AC"]

任何提示/建议/帮助都将非常感谢!

2 个答案:

答案 0 :(得分:2)

PHP已经为此操作提供了一个特定的工具:array_walk_recursive();所以没有必要重新发明轮子。

在准备好json数据后,只需一个函数调用就可以快速,简洁地完成任务。

省略第一个macAddress(不需要的)值是通过仅传递带有' children'的键的子数组来完成的。到array_walk_recursive()

代码:(Demo

$array=json_decode($testDataJson,true)['children'];  // this avoids including the first "non-children" macAddress value.
array_walk_recursive($array,function($v,$k)use(&$result){if($k==='macAddress') $result[]=$v;});
var_export($result);

结果:

array (
  0 => '98:D6:D6:D8:FF:34',
  1 => '44:66:E9:A1:2C:DC',
  2 => 'D8:C2:A9:1C:44:47',
  3 => '22:CD:E6:8F:8C:B8',
  4 => '13:E4:AB:33:36:AC',
)

或者,可以像这样准备输入数组:

$array=array_diff_key(json_decode($testDataJson,true),['macAddress'=>'']);

这将确保您不会意外地抓取任何非子级macAddress值。

答案 1 :(得分:1)

就像Barmar siad"你有无限的递归。"

这是我的解决方案。它打印出所有mac地址

function recursiveKeyFinder($array) {
    $result = [];

    $result[] = $array['macAddress'];
    if (isset($array['children'])) {
        foreach($array['children'] as $child){
            $result = array_merge($result,recursiveKeyFinder($child));
        }
    }
    return $result;
}

结果

array (size=6)
  0 => string '10:20:30:40:50:81' (length=17)
  1 => string '98:D6:D6:D8:FF:34' (length=17)
  2 => string '44:66:E9:A1:2C:DC' (length=17)
  3 => string 'D8:C2:A9:1C:44:47' (length=17)
  4 => string '22:CD:E6:8F:8C:B8' (length=17)
  5 => string '13:E4:AB:33:36:AC' (length=17)

希望这可以提供帮助