3

I have two arrays, one is a multidimensional array which holds information, the other is a simple array which holds values for the order I want the first array in.

For example, I want my first array to be ordered by ID, by the values in the second array.

$users array:

array(3) {
    [0] => array(3) {
            'id' => 1,
            'name' => 'John Smith',
            'email' => '[email protected]',
        },
    [2] => array(3) {
            'id' => 2,
            'name' => 'Jane Smith',
            'email' => '[email protected]',
        },
    [0] => array(3) {
            'id' => 3,
            'name' => 'Jack Smith',
            'email' => '[email protected]',
        },
}

$order array:

array(3) {
    [0] => '2',
    [1] => '3',
    [2] => '1',
}

What I would like the outcome of the sorted array to be:

array(3) {
    [0] => array(3) {
            'id' => 2,
            'name' => 'Jane Smith',
            'email' => '[email protected]',
        },
    [2] => array(3) {
            'id' => 3,
            'name' => 'Jack Smith',
            'email' => '[email protected]',
        },
    [0] => array(3) {
            'id' => 1,
            'name' => 'John Smith',
            'email' => '[email protected]',
        },
}

So as you can see, I would like the array keys to be reindexed, so they are always sequential starting from 0, but for the values of each element in the $users array to be re ordered.

1

3 Answers 3

5

You can do this like this:

// Index users by ID
$users = array_combine(
    array_column($users, 'id'),
    $users
);

// Order the users
$users = array_map(function ($id) use ($users) {
    return $users[$id];
}, $order);

Here I used array_combine() function, that creates array by mapping given keys to values. For the keys I used all the id's in a sequential order (grabbed them with array_column()).

Having an array in such form, I can loop over $order array and grab the values from $users array by index, that actually have the value of id now.

Instead of looping with foreach I used array_map() function. If you have a collection (i.e. array) it is better to use higher order functions to process them. If you are a beginner it can be overwhelming, but you have to learn this, as this is the way things done nowadays.

Here is working example.

Sign up to request clarification or add additional context in comments.

Comments

1

You can use usort to achieve this :

        // the key order of each id
        $orderIdKeys  = array_flip($order);

        usort($users, function ($u1, $u2)  use ($orderIdKeys) {

            // compare the keys of the ids in the $order array
            return $orderIdKeys[$u1['id']] >= $orderIdKeys[$u2['id']] ?  1 : -1;
        });

Then $users should be ordered.

The usort here is comparing users based on the position ( which is $orderIdKeys[$u1['id']] ) of each user id in $order array, If the position of $u1['id'] is greater than the position of $u2['id'] the callback returns 1 which means $u2 should be placed before $u1 in the final ordered array

Comments

-1

I think that this should do the job:

$array = array(
    array(
            'id' => 2,
            'name' => 'Jane Smith',
            'email' => '[email protected]',
    ),
    array(
            'id' => 3,
            'name' => 'Jack Smith',
            'email' => '[email protected]',
    ),
    array(
            'id' => 1,
            'name' => 'John Smith',
            'email' => '[email protected]',
    ),
);

function cmp_by_optionNumber($a, $b) {
  return $a["id"] - $b["id"];
}
usort($array, "cmp_by_optionNumber");

var_dump($array);

It will sort your main array by the values of the "id" keys in the subarrays.

1 Comment

This doesn't answer the question

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.