Intereting Posts

Flatten Array: сохранить индекс, значение равное положению в массиве

У меня была небольшая проблема, пытаясь сгладить массивы определенным образом.

Вот вид print_r массива, который я хочу сгладить:

 Array ( [1] => Array ( [8] => 1 [9] => 2 [10] => Array ( [15] => Array ( [22] => 1 ) [21] => 2 ) [11] => Array ( [16] => Array ( [23] => 1 ) ) ) [2] => Array ( [12] => 1 ) [3] => Array ( [13] => 1 ) [4] => Array ( [14] => 1 ) [5] => 5 [6] => 6 [7] => 7 ) 

То, что я пытаюсь создать, – это массив, который сохраняет указанные выше индексы, но значение равно его позиции в массиве, подобно исходному индексу (начиная с нуля).

Вот желаемый результат:

 Array ( [1] => 1 [2] => 2 [3] => 3 [4] => 4 [5] => 5 [6] => 6 [7] => 7 [8] => 1 [9] => 2 [10] => 3 [11] => 4 [12] => 1 [13] => 1 [14] => 1 [15] => 1 [16] => 1 [21] => 2 [22] => 2 [23] => 1 ) 

Не зря, 17-20 пропали без вести.

Моя функция такова:

 function array_flatten ($array) { $result = array (); $count = 1; while ($index = current($array)) { $result[key($array)] = $count; if (is_array($index)) { $result = array_merge(array_flatten($index), $result); } next($array); $count++; } return $result; } 

Линия $result = array_merge(array_flatten($index), $result); это проблемы. Он возвращает:

 Array ( [1] => 1 [2] => 2 [3] => 3 [4] => 4 [5] => 5 [6] => 6 [7] => 7 ) 

Однако, если я запускаю var_dump(array_flatten($index)); в той же строке он возвращает все массивы, которые я хочу объединить с переменной $result .

 array 22 => int 1 array 15 => int 1 21 => int 2 array 23 => int 1 array 16 => int 1 array 8 => int 1 9 => int 2 10 => int 3 11 => int 4 array 12 => int 1 array 13 => int 1 array 14 => int 1 

Кажется, что array_merge фактически не объединяет эти массивы.

Есть ли что-то, что я делаю неправильно? Любые слова руководства очень ценятся. Спасибо.

Обновить

Решено!

Функция, которая делает требуемую, выглядит следующим образом:

 function array_flatten($array, &$result = array()) { $count = 1; foreach($array as $index => $value) { $result[$index] = $count; if(is_array($value)) { array_flatten($value, $result); } $count++; } return $result; } 

 function flatten_array($array, &$result) { foreach($array as $key => $value) { if(is_array($value)) { flatten_array($value, $result); } else { $result[$key] = $value; } } } 

Чтобы использовать это, проверьте пример кода ниже:

 $flattened = array(); $test = array( 1 => 1 , 3 => 2 , array(2 => 4, 4 => 6) , 5 => 3 , array(7 => 9, 8 => 7, 9 => 5) ); flatten_array($test, $flattened); // Now $flattened contains the flattened array 

После того, как вы уточнили свой вопрос, я был немного удивлен, что вы приняли ответ, который не возвращает данные, которые вы ожидали. (Я уже видел, что вы добавили свое решение на свой вопрос.)

Что я сделал: я взял функцию из @Arjan в качестве базы и запустил ее на входные данные вопросов и сравнил ее с ожидаемыми данными. Затем я немного поработал над этим. Это то, что я придумал (в результате):

 # COMP EXPECTED . ACTUAL #00: == Array . Array #01: == ( . ( #02: == [1] => 1 . [1] => 1 #03: == [2] => 2 . [2] => 2 #04: == [3] => 3 . [3] => 3 #05: == [4] => 4 . [4] => 4 #06: == [5] => 5 . [5] => 5 #07: == [6] => 6 . [6] => 6 #08: == [7] => 7 . [7] => 7 #09: == [8] => 1 . [8] => 1 #10: == [9] => 2 . [9] => 2 #11: == [10] => 3 . [10] => 3 #12: == [11] => 4 . [11] => 4 #13: == [12] => 1 . [12] => 1 #14: == [13] => 1 . [13] => 1 #15: == [14] => 1 . [14] => 1 #16: == [15] => 1 . [15] => 1 #17: == [16] => 1 . [16] => 1 #18: == [21] => 2 . [21] => 2 #19: != [22] => 2 . [22] => 1 #20: == [23] => 1 . [23] => 1 #21: == ) . ) #22: == . 

Похоже, что ваши ожидаемые данные имеют ошибку для позиции 22.

Это измененная функция ( Demo ):

 function flatten_array($array, &$result = null) { $r = null === $result; $i = 0; foreach($array as $key => $value) { $i++; if(is_array($value)) { $result[$key] = $i; flatten_array($value, $result); } else { $result[$key] = $value; } } if ($r) { ksort($result); return $result; } } $actual = flatten_array($input);