Итерация по массиву рекурсивно вызывает неверные результаты в функции обратного вызова - PullRequest
0 голосов
/ 21 декабря 2018

Я пытаюсь рекурсивно перебирать каждый элемент массива, чтобы получить значения, где ключ равен page_id или content_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_walk или array_walk_recursive, но я предпочитаю этот подход, так как, на мой взгляд, он более элегантный и читаемый.

1 Ответ

0 голосов
/ 21 декабря 2018

Ваш код выглядит нормально.Проблема в том, что 0 == 'content_id' равно True switch в PHP использует свободное (==) сравнение.И поскольку в terms у вас есть два значения без строковых ключей, они автоматически индексируются, начиная с 0. Таким образом, вы получаете не когда ваша функция находит

'content_id' => 6

, а когда она находит

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

РЕДАКТИРОВАТЬ: Итог - вы должны использовать if со строгим сравнением === в этом случае (или везде использовать строковые ключи).

...