Skip to main content

Custom array order in PHP

Published ago
Updated ago
6 min read

Recently I found myself in the need to create a list of elements in a very specific order while working with an array in PHP, fortunately it turns out that the way to achieve it is very simple, thanks to PHP offering us the usort function. Next, I will mention how to achieve a custom order of arrays in PHP.

The code

Taking the following example, I will explain what it consists of:

1<?php
2/**
3 * Array to order.
4 * Let's assume we receive this array from an API where we have no control.
5 */
6$my_array = [
7 'DO',
8 'FA',
9 'LA',
10 'MI',
11 'RE',
12 'SI',
13 'SOL',
14];
15
16/**
17 * Order we want, where we have control.
18 */
19 $custom_order = [
20 'DO',
21 'RE',
22 'MI',
23 'FA',
24 'SOL',
25 'LA',
26 'SI',
27 ];
28
29/**
30 * We order the array.
31 */
32usort(
33 $my_array,
34 function( $a, $b ) use ( $custom_order ) {
35 $a_order = array_search( $a, $custom_order );
36 $b_order = array_search( $b, $custom_order );
37
38 if ( false === $a_order ) {
39 $a_order = 999;
40 }
41
42 if ( false === $b_order ) {
43 $b_order = 999;
44 }
45
46 return $a_order - $b_order;
47 }
48);
49
50var_export( $my_array );
51

What is happening?

What the function does is not very complex, let's say, it is a loop that iterates over each element in the array, and compares them with each other, finally assigning them a temporary value. The magic happens here when using array_search, which returns the index of the element within the array. The lower the assigned value, the higher priority is given in the order.

1/**
2 * Array with emphasized indices:
3 */
4$custom_order = [
5 [0] => 'DO',
6 [1] => 'RE',
7 [2] => 'MI',
8 [3] => 'FA',
9 [4] => 'SOL',
10 [5] => 'LA',
11 [6] => 'SI',
12];
13

For example, when our algorithm compares DO vs MI, it is comparing [0] vs [2], which are the indices of those elements in the array:

1if ( false === $a_order ) {
2 $a_order = 999;
3}
4
5if ( false === $b_order ) {
6 $b_order = 999;
7}
8

If it does not find the values within the array (false === $a_order), it automatically assigns a value of 999, which would place them at the end of priorities.

1return $a_order - $b_order;
2

Finally, it returns the result of 0 - 2, or -2, which would place DO above MI, at the moment when MI vs DO is compared, the operation would be 2 - 0, with a result of 2 which would keep MI below DO in priority.

In this way, when the comparisons are finished, we will have our custom order of arrays in PHP ready.

Note

UPDATE 09-27-23

If I already have the order I want defined, why do I need to sort another array?

After my original publication, I realized that it doesn't make much sense to use an example of a single-level array, since immediately after the same array is being placed but sorted, so what's the point of this?.

The real utility comes when we have to sort multidimensional arrays, in this way, based on the value of the array, we can define in what place we want to show it, for example:

1/**
2 * Array of teams received from an API
3 */
4$teams = [
5 [
6 'id' => 9384,
7 'league' => 'NBA',
8 'type' => 'basketball',
9 ],
10 [
11 'id' => 89732,
12 'league' => 'MLB',
13 'type' => 'baseball',
14 ],
15 [
16 'id' => 52,
17 'league' => 'MLS',
18 'type' => 'football',
19 ],
20];
21
22/**
23 * Order by preference
24 */
25$custom_order = [
26 'football',
27 'basketball',
28 'baseball',
29];
30
31/**
32 * We order the array.
33 */
34usort( $teams, ... ); // Same as we used before.
35
36var_export( $teams );
37
38/**
39[
40 [
41 'id' => 52,
42 'league' => 'MLS',
43 'type' => 'football',
44 ],
45 [
46 'id' => 9384,
47 'league' => 'NBA',
48 'type' => 'basketball',
49 ],
50 [
51 'id' => 89732,
52 'league' => 'MLB',
53 'type' => 'baseball',
54 ],
55];
56*/
57

Further reading