繁体   English   中英

PHP搜索JSON而不循环

[英]PHP search JSON without looping

我有一个很大的JSON数组,这是查询Icinga2监视系统的API的结果。

我在代码中使用了json_decode这样的代码对其进行解码:

$response = json_decode($array, true);

我可以看到输出看起来像这样:

        Array
            (
                [results] => Array
                    (
                        [0] => Array
                            (
                                [attrs] => Array
                                    (
                                        [__name] => HOSTNAME0
                                        [acknowledgement] => 0
                                        [acknowledgement_expiry] => 0
                                        ...
                                        ...
                                        [state] => 0
                                        [state_type] => 1
                                 [meta] => Array
                                     (
                                     )

                                 [name] => HOSTNAME0
                                 [type] => Host
            )


                        [1] => Array
                            (
                                [attrs] => Array
                                    (
                                        [__name] => HOSTNAME1
                                        [acknowledgement] => 0
                                        [acknowledgement_expiry] => 0
                                        ...
                                        ...
                                        [state] => 0
                                        [state_type] => 1   
                                 [meta] => Array
                                     (
                                     )

                                 [name] => HOSTNAME1
                                 [type] => Host
            )

总共有400条记录,结构相当复杂,但我真正感兴趣的只有名称和状态字段。 基本上,我的脚本列出了另一个来源的150个主机名,我要为每个主机名做一个工作,在数组中搜索它,然后返回该主机的state字段的值。 到目前为止,我一直在努力做到这一点,而又没有遍历150个主机名中每个主机名的整个数组。 必须有一种更有效的方法来基于主机名在数组中进行查找并返回单个值,但我无法弄清楚。

给定的是, name字段在json结果内部没有逻辑排序,因此无法在每个元素上至少查看一次。 如果它们按字母顺序排序,则可以使用简单的二进制搜索,该结果将以O(log(n))

另一件事是,如果必须搜索多个名称,则可以将它们放在名称关联的数组中。 这样,构建列表的初始开销为O(n) ,随后的每个搜索都将返回O(1)的状态。

// building the array
$states = [];
foreach ($items as $item) {
    $states[$item['name']] = $item['state'];
}

looking for HOSTNAME1
$state = $states['HOSTNAME1'];

我希望源数据数组的布局正确,因为格式与原始问题有点混淆。 但是主要思想是使用array_column提取“属性”并通过该数组的“名称”元素键入结果。

$response = Array(
    "results" => Array(
        0 => Array(
            "attrs" => Array(
                "__name" => "HOSTNAME0",
                "acknowledgement" => 0,
                "acknowledgement_expiry" => 0,
                "state" => 0,
                "state_type" => 1
            ),
            "name" => "HOSTNAME0",
            "type" => "Host"
        ),
        1 => Array(
            "attrs" => Array(
                "__name" => "HOSTNAME1",
                "acknowledgement" => 0,
                "acknowledgement_expiry" => 0,
                "state" => 2,
                "state_type" => 1
            ),
            "name" => "HOSTNAME1",
            "type" => "Host1"
        )
    )
);

$extract = array_column($response["results"], "attrs", "name");
print_r($extract);

借助样本数据,可以得出...

Array
(
    [HOSTNAME0] => Array
        (
            [__name] => HOSTNAME0
            [acknowledgement] => 0
            [acknowledgement_expiry] => 0
            [state] => 0
            [state_type] => 1
        )

    [HOSTNAME1] => Array
        (
            [__name] => HOSTNAME1
            [acknowledgement] => 0
            [acknowledgement_expiry] => 0
            [state] => 2
            [state_type] => 1
        )

)

因此,要使用名称查找任何服务器,您将使用

echo "HOSTNAME1=".$extract["HOSTNAME1"]["state"].PHP_EOL;

如果您只想要状态字段(如您所要求的)并且想要简化数组,则可以使用...

array_walk($extract, function(&$data) {$data=$data["state"];});
print_r($extract);

array_walk()遍历数组,仅将状态字段复制为条目,因此其结果是...

Array
(
    [HOSTNAME0] => 0
    [HOSTNAME1] => 2
)

所以现在你要做...

echo "HOSTNAME1=".$extract["HOSTNAME1"].PHP_EOL;

暂无
暂无

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

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