2
votes

I have a multidimensional array in php and i need to change the column order with the order of a second simple array.

EDIT: Although both arrays are the same in regard of values and keys, im using this for export with phpexcel, and it generates the xls file with the order of the given array. I need to change that order so the xls file looks that way.

The array looks like this:

Array
(
    [0] => Array
        (
            [name] => Name1
            [sn] => Sn1
            [somenumber] => 43234234
        )

    [1] => Array
        (
            [name] => Name2
            [sn] => Sn2
            [somenumber] => 4564564
        )

    [2] => Array
        (
            [name] => Name3
            [sn] => Sn3
            [somenumber] => 6575647456745
        )
)

And the second array is this:

Array
        (
            [0] => sn
            [1] => name
            [2] => somenumber
        )

What i need is the first array to be ordered based on the second so it looks like this:

Array
(
    [0] => Array
        (
            [sn] => Name1
            [name] => Sn1
            [somenumber] => 43234234
        )

    [1] => Array
        (
            [sn] => Name2
            [name] => Sn2
            [somenumber] => 4564564
        )

    [2] => Array
        (
            [sn] => Name3
            [name] => Sn3
            [somenumber] => 6575647456745
        )
)
3
Unless I'm missing something the first and last array in your question are the same. How they are displayed when using print_r doesn't really matter, or shouldn't, and since the indexes and values are the same so are the arrays. - Dave
Im using this array for export in an xls file with phpexcel. It generates the xls with the order of the keys, and i need a different order. The data, as you say, is the same. - Emepese

3 Answers

1
votes

If all keys always present

// Make template array with correct order of keys
$template = array_flip($second);

foreach($array as &$x) {
   // replace values in template
   $x = array_replace($template, $x);
}

demo

1
votes

this is how you can sort your array: $template array:

//template array
$reference = array('sn', 'name', 'somenumber');
$array_to_sort = Array
(
    "0" => Array
        (
            "somenumber" => "Name1",
            "sn" => "Sn1",
            "name" => "43234234"
        ),

    "1" => Array
        (
            "sn" => "Name2",
            "somenumber" => "4564564",
            "name" => "Sn2"
        ),

    "2" => Array
        (
            "sn" => "Name3",
            "name" => "Sn3",
            "somenumber" => "6575647456745"
        )
);
    $ordered_array = [];
    foreach ($array_to_sort as $key => $value) {
      $ordered_array[] = array_replace(array_flip($reference), $value);
    }

    print_r($ordered_array);
0
votes

This is a late answer, but in modern PHP (i.e. >= PHP7.4) we could use nested array_maps with arrow functions which is basically a one-liner, albeit not a very readable one. The outer array_map traverses the input $array line by line, and the inner array_map traverses the array of the desired new column order $order column by column, or index by index.
Expressed as a function it would look like in the code block below with arrays as in the original question (and the solution works for both associative and standard arrays).
As we are transforming an array, the array_map is the preferable way as we don't need to create intermediary variables like with a foreach loop.

$data = Array
(
    "0" => Array
        (
            "somenumber" => "Name1",
            "sn" => "Sn1",
            "name" => "43234234"
        ),

    "1" => Array
        (
            "sn" => "Name2",
            "somenumber" => "4564564",
            "name" => "Sn2"
        ),

    "2" => Array
        (
            "sn" => "Name3",
            "name" => "Sn3",
            "somenumber" => "6575647456745"
        )
);

$order = array('sn', 'name', 'somenumber');

function reorderColumns ($array, $order) {
    return array_map(fn ($line) => 
        array_map(fn ($index) => $line[$index], $order),
    $array);
}

print_r(reorderColumns($data, $order));