5

I have one array (left) that contains a list of elements, the goal is to sort another arrays (right) keys with the values from the left array.

The left array

Array
(
    [0] => ID
    [1] => FirstName
    [2] => LastName
    [3] => Address
)

The right array

Array
(
    [0] => Array
    (
        [FirstName] => Pim
        [Address] => Finland
        [LastName] => Svensson
        [ID] => 3
    )
    [1] => Array
    (
        [FirstName] => Emil
        [Address] => Sweden
        [LastName] => Malm
        [ID] => 5
    )
)

What I'm trying to accomplish would be similar to this

Array
(
    [0] => Array
    (
        [ID] => 3
        [FirstName] => Pim
        [LastName] => Svensson
        [Address] => Finland
    )

I'm running PHP5.3.

6 Answers 6

8
$output = array();
foreach ( $right as $array ) {
    foreach ( $left as $field ) {
        $temp[$field] = $array[$field];
    }
    $output[] = $temp;
}
Sign up to request clarification or add additional context in comments.

Comments

3

You can use uksort() which lets you sort array keys by a user defined function. E.g.:

function sort_by_array($array) {
    // create a sorting function based on the order of the elements in the array
    $sorter = function($a, $b) use ($array) {
        // if key is not found in array that specifies the order, it is always smaller
        if(!isset($array[$a])) return -1; 
        if($array[$a] > $array[$b]) {
            return 1;
        }
        return ($array[$a] == $array[$b]) ? 0 : -1;
    };
    return $sorter;
}
// $array contains the records to sort
// $sort_array is the array that specifies the order
foreach($array as &$record) {
    uksort($record, sort_by_array(array_flip($sort_array)));
}

I make use of the possibility in 5.3 to define functions dynamically and I use array_flip() to transform:

Array
(
    [0] => ID
    [1] => FirstName
    [2] => LastName
    [3] => Address
)

to

Array
(
    [ID] => 0
    [FirstName] => 1
    [LastName] => 2
    [Address] => 3
)

This makes it easier to compare the keys later.

2 Comments

1+ for being flexible, but I think it's overly complex for this particular case.
@chris: Yes, in this case, depending what the OP really wants to do with the array, it might be to complex. But I wondered why no one mentioned this method and I wanted to show that it is possible.
2

You must explode the array Store the array in a variable like this

$array = Array
(
    [0] => Array
    (
        [ID] => 3
        [FirstName] => Pim
        [LastName] => Svensson
        [Address] => Finland
    );

and then explode the array after exploding the array you will get the parameters of the array seperated then you can use implode function the arrange them in anyorder as you wish

Comments

1

@MatteoRiva's unexplained snippet is probably the most efficient way to implement the second level key repositioning, but for the sake of exploration of the programming language, I'll offer some alternatives.

You can use array_map() to overwrite your flipped "left" array with the "right" array values. The call of array_flip() will only occur on the first iteration. Demo

var_export(
    array_map(
        function ($row) use ($left) {
            static $keys = array_flip($left);
            return array_replace($keys, $row);
        },
        $right
    )
);

Thinking a little more abstractly, you can affect all members of the 2d array by spreading the rows inside of array_multisort(), but first you'll need the first parameter to determine the sorting. Demo

$left = array_flip(['ID', 'FirstName', 'LastName', 'Address']);

array_multisort(
    array_map(
        fn($k) => $left[$k],
        array_keys($right[0] ?? [])
    ),
    ...$right
);
var_export($right);

Or populate a 2d array with the correctly ordered keys using the left array, then use array_replace_recursive() to overwrite that dummy array with the row values from the right array. Demo

var_export(
    array_replace_recursive(
        array_fill(0, count($right), array_fill_keys($left, null)),
        $right
    )
);

uksort() can be called within array_walk() and leverage the flipped left array while sorting each row. Demo

$left = array_flip(['ID', 'FirstName', 'LastName', 'Address']);

array_walk(
    $right,
    fn(&$row) => uksort(
        $row,
        fn($a, $b) => $left[$a] <=> $left[$b]
    )
);
var_export($right);

Comments

0

I'd take a step back and look at what you really need to do. The array is associative, so you can access the correct element instantly, right? So you don't really need it to be in order, unless you print output with foreach.

I'd suggest one of the following solutions:

  1. If you need the "right" array to be in key-order, then look at the database query / similar and select the columns in the order you need them.
  2. Foreach person you want to print, look up the order in the "left" array, then print the corresponding value of that key in the "right" array.

1 Comment

I don't select anything from a db, I get the array from an xml which is loaded with simplexml!
0

Well, your question it's uncommon, usually the associative arrays are used to resolve any problems about "position". Anyway, there are many way to do what you are looking for what are you looking for.

You can use list() but it's position based:

foreach($oldArray as $o)
{
    list($firstName,$lastName,$address,$id)=$oldArray;
    $newArray[]=array($id,$firstName,$lastName,$address);
}

But the best way to solve your problem it's fill the array directly in the right order instead of re-sort after :)

1 Comment

Thanks! I second that, but I get the information in xml from another service, this way I can't always guarantee the order of the data. Thus this odd quest! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.