【问题标题】:Iterating over an array recursively causes invalid results in callback function递归遍历数组会导致回调函数中的无效结果
【发布时间】:2018-12-20 21:33:04
【问题描述】:

我正在尝试递归遍历数组的每个元素,以获取键等于 page_idcontent_id 的值。

问题在于,在回调函数中,在 switch 语句中,我得到了完全奇怪的行为,大小写匹配但值不同。

这让我发疯了很长一段时间。我什至尝试使用像if($key === 'component_id') print $key; die(); 这样的严格比较。我期望得到“component_id”作为输出,但得到“0”。这怎么可能?

在写这个问题时,我也注意到在某个时候存在索引数组时会发生这种情况,但我不确定这是否是问题。

这是来自完整解决方案的示例代码。

谢谢。

<?php

class Arr
{
    public static function map($array, $callback, $recursive = false)
    {
        foreach ($array as $key => $value) {
            $array[$key] = $callback($key, $value);
            if($recursive && is_array($array[$key])) {
                $array[$key] = static::map($array[$key], $callback, true);
            }
        }
        return $array;
    }
}

$data = [
    'id' => 12,
    'data' => [
        'terms' => [
            [
                'href' => null,
                'icon' => 'lock',
                'target' => '_blank'
            ],
            [
                'href' => 'http://example.com',
                'icon' => 'lock',
                'target' => '_blank'
            ]
        ],
        'license_info' => [
            'content_id' => 6
        ]
    ]
];

$contents = [];
$pages = [];

Arr::map($data, function ($key, $value) use (&$contents, &$pages) {
    switch ($key) {
        case 'content_id':
            print $key; die(); // 0  ?????
            $contents[] = $value;
            break;
        case 'page_id':
            $pages[] = $value;
            break;
    }

    return $value;
}, true);

我希望输出是component_id,但我得到了0

我也知道我可以使用array_walkarray_walk_recursive,但我更喜欢这种方法,因为我认为它更优雅、更易读。

【问题讨论】:

    标签: php recursion switch-statement comparison


    【解决方案1】:

    您的代码看起来不错。问题是0 == 'content_id'True。而 PHP 中的 switch 使用松散的 (==) 比较。因为在terms 中有两个没有字符串键的值,所以它们会自动从 0 开始索引。 所以你得到的不是当你的函数找到时

    'content_id' => 6
    

    但是当它找到时

    /* 0 => */
    [
       'href' => null,
       'icon' => 'lock',
       'target' => '_blank'
    ],
    

    编辑: 底线是 - 在这种情况下,您必须使用 if 和严格比较 ===(或在任何地方使用字符串键)。

    【讨论】:

    • @rms 谢谢 ;),我无法想象 0 == 'content_id' 是否为 True。另外,当使用严格比较时,我保持 switch 语句完好无损,所以这就是我认为有问题的原因。
    • @GiorgiBotsvadze 我知道,这太疯狂了 :) 让它变得更好 1 == 'content_id'False :DD
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多