0

I wrote a method to reorder all numeric keys on an array.

You can see in code below that i have an array with unsorted keys. This keys (f.e. 200, 2) should be reordered (f.e. 0, 1) recursively. This should work in php 5.6 up to 7 but at least in 7

Perfectly works but seems very slow. I wonder if anybody knows how to get this faster.

Code and Test:

function reorderKeysRecursively(array $array)
{
    foreach ($array as $key => &$value) {
        if (is_array($value)) {
            $array[$key] = reorderKeysRecursively($value);
        }
    }
    return array_slice($array, 0);
}

$array = [
    2 => [
        'foo' => 'bar',
        2     => 'baz',
        'bar' => 3,
        33    => [
            55 => [
                2 => [
                    55 => [
                        'foo' => 'bar'
                    ],
                ],
            ],
        ],
        'baz' => 4,
    ],
];

$start = microtime(true);
for ($i = 0; $i < 200000; $i++) {
    reorderKeysRecursively($array);
}
echo "elapsed: " . (microtime(true) - $start) . PHP_EOL;

$expect = json_encode(
    [
        0 => [
            'foo' => 'bar',
            0     => 'baz',
            'bar' => 3,
            1     => [
                0 => [
                    0 => [
                        0 => [
                            'foo' => 'bar',
                        ],
                    ],
                ],
            ],
            'baz' => 4,
        ],
    ]
);
$result = json_encode(reorderKeysRecursively($array));
echo "is expected result: " . (var_export($result === $expect, true)) . PHP_EOL;

Thanks for helping! /cottton

cottton
  • 1,522
  • 14
  • 29
  • What sense does the call to `array_slice()` make for this anyway? That function is to take a part of the array, which you do not do. – arkascha Feb 11 '17 at 16:45
  • In general recursive algorithms are slow. Using an iterator approach is faster, but more complicated to implement. Best bet probably is to use one of the recursive array sorting functions builtin to php, since those are per definition more efficient (no interpretation required). – arkascha Feb 11 '17 at 16:47
  • Im using `array_slice` only because this function reorders all numeric keys. Actually that is what im looking for: another way/function to reorder them. EDIT: but only numeric keys. Others (string) must stay as they are. – cottton Feb 12 '17 at 01:45
  • I may found the solution: `array_merge($array)` should do the job. Will test soon. @see http://stackoverflow.com/a/24332702/3411766 – cottton Feb 12 '17 at 01:54
  • @mickmackusa I had hope sombody had a better solution. But i think `array_merge` is the way to go here since it does perfectly what i need: reorder numeric keys and leave the rest alone. Im posting an answer for that. – cottton Mar 13 '17 at 20:56

1 Answers1

0

Way to go (until somebody has a better solution) is array_merge on each array level.

function reorderKeysRecursively(array &$array)
{
    foreach ($array as $key => &$value) {
        if (is_array($value)) {
            $array[$key] = reorderKeysRecursively($value);
        }
    }
    return array_merge($array);
}

Out

[
    0 => [                  // before: 2
        'foo' => 'bar',
        0     => 'baz',     // before: 2
        'bar' => 3,
        1     => [          // before: 33
            0 => [          // before: 55
                0 => [      // before: 2
                    0 => [  // before: 55
                        'foo' => 'bar',
                    ],
                ],
            ],
        ],
        'baz' => 4,
    ],
]
cottton
  • 1,522
  • 14
  • 29