Flatten Array: сохранить индекс, значение равно положению в массиве - PullRequest
3 голосов
/ 15 июля 2011

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

Вот 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;
}

Ответы [ 2 ]

2 голосов
/ 15 июля 2011
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
0 голосов
/ 16 июля 2011

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

Что я сделал: я взял функцию из @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.

Это модифицированная функция ( Демо ):

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);
...