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

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

2

Решение

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

'content_id' => 6

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

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

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

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector