How to Sort a Multi-dimensional Array by Value

PhpArraysSortingMultidimensional Array

Php Problem Overview


How can I sort this array by the value of the "order" key?

Even though the values are currently sequential, they will not always be.

Array
(
    [0] => Array
        (
            [hashtag] => a7e87329b5eab8578f4f1098a152d6f4
            [title] => Flower
            [order] => 3
        )

    [1] => Array
        (
            [hashtag] => b24ce0cd392a5b0b8dedc66c25213594
            [title] => Free
            [order] => 2
        )

    [2] => Array
        (
            [hashtag] => e7d31fc0602fb2ede144d18cdffd816b
            [title] => Ready
            [order] => 1
        )
)

Php Solutions


Solution 1 - Php

Try a usort. If you are still on PHP 5.2 or earlier, you'll have to define a sorting function first:

function sortByOrder($a, $b) {
    return $a['order'] - $b['order'];
}

usort($myArray, 'sortByOrder');

Starting in PHP 5.3, you can use an anonymous function:

usort($myArray, function($a, $b) {
    return $a['order'] - $b['order'];
});

And finally with PHP 7 you can use the spaceship operator:

usort($myArray, function($a, $b) {
    return $a['order'] <=> $b['order'];
});

To extend this to multi-dimensional sorting, reference the second/third sorting elements if the first is zero - best explained below. You can also use this for sorting on sub-elements.

usort($myArray, function($a, $b) {
    $retval = $a['order'] <=> $b['order'];
    if ($retval == 0) {
        $retval = $a['suborder'] <=> $b['suborder'];
        if ($retval == 0) {
            $retval = $a['details']['subsuborder'] <=> $b['details']['subsuborder'];
        }
    }
    return $retval;
});

If you need to retain key associations, use uasort() - see comparison of array sorting functions in the manual.

Solution 2 - Php

function aasort (&$array, $key) {
    $sorter = array();
    $ret = array();
    reset($array);
    foreach ($array as $ii => $va) {
        $sorter[$ii] = $va[$key];
    }
    asort($sorter);
    foreach ($sorter as $ii => $va) {
        $ret[$ii] = $array[$ii];
    }
    $array = $ret;
}

aasort($your_array, "order");

Solution 3 - Php

I use this function:

function array_sort_by_column(&$arr, $col, $dir = SORT_ASC) {
    $sort_col = array();
    foreach ($arr as $key => $row) {
        $sort_col[$key] = $row[$col];
    }

    array_multisort($sort_col, $dir, $arr);
}

array_sort_by_column($array, 'order');

Edit This answer is at least ten years old, and there are likely better solutions now, but I am adding some extra info as requested in a couple of comments.

It works because array_multisort() can sort multiple arrays. Example input:

Array
(
    [0] => Array
        (
            [hashtag] => a7e87329b5eab8578f4f1098a152d6f4
            [title] => Flower
            [order] => 3
        )

    [1] => Array
        (
            [hashtag] => b24ce0cd392a5b0b8dedc66c25213594
            [title] => Free
            [order] => 2
        )

First $sort_col is made which is an two dimensional array with the values being what we want to sort by and the keys matching the input array. For example for this input, choosing key $sort_col "order" we get:

Array
(
    [0] => 3,
    [1] => 2
)

array_multisort() then sorts that array (resulting in key order 1, 0) but this is only the two dimensional array. So the original input array is also passed as the $rest argument. As the keys match it will be sorted so its keys are also in the same order, giving the desired result.

Note:

  • it is passed by reference so that the supplied array is modified in place.
  • array_multisort() can sort multiple additional array like this, not just one

Solution 4 - Php

To achieve this we can use "array_multisort" method which 'Sorts multiple or multi-dimensional arrays'. It's method parameters are

  • $keys - an array being sorted
  • SORT_ASC - sort order (ascending)
  • sort flags (compare items normally(don't change types) or numerically or as strings)
  • $new - then rest of the arrays. Only elements corresponding to equivalent elements in previous
    arrays are compared.

'sort flags' is SORT_REGULAR by default and it is omitted.

$new = [
    [
        'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4',
        'title' => 'Flower',
        'order' => 3,
    ],
    [
        'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594',
        'title' => 'Free',
        'order' => 2,
    ],
    [
        'hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b',
        'title' => 'Ready',
        'order' => 1,
    ],
];
$keys = array_column($new, 'order');
array_multisort($keys, SORT_ASC, $new);
var_dump($new);

Result:

Array
(
    [0] => Array
        (
            [hashtag] => e7d31fc0602fb2ede144d18cdffd816b
            [title] => Ready
            [order] => 1
        )
    [1] => Array
        (
            [hashtag] => b24ce0cd392a5b0b8dedc66c25213594
            [title] => Free
            [order] => 2
        )
    [2] => Array
        (
            [hashtag] => a7e87329b5eab8578f4f1098a152d6f4
            [title] => Flower
            [order] => 3
        )
)

Solution 5 - Php

I usually use usort, and pass my own comparison function. In this case, it is very simple:

function compareOrder($a, $b)
{
  return $a['order'] - $b['order'];
}
usort($array, 'compareOrder');

In PHP 7 using the spaceship operator:

usort($array, function($a, $b) {
    return $a['order'] <=> $b['order'];
});

Solution 6 - Php

To sort the array by the value of the "title" key, use:

uasort($myArray, function($a, $b) {
    return strcmp($a['title'], $b['title']);
});

strcmp compare the strings.

uasort() maintains the array keys as they were defined.

Solution 7 - Php

Use array_multisort(), array_map()

array_multisort(array_map(function($element) {
      return $element['order'];
  }, $array), SORT_ASC, $array);
  
print_r($array);

DEMO

Solution 8 - Php

$sort = array();
$array_lowercase = array_map('strtolower', $array_to_be_sorted);
array_multisort($array_lowercase, SORT_ASC, SORT_STRING, $alphabetically_ordered_array);

This takes care of both upper and lower case alphabets.

Solution 9 - Php

The most flexible approach would be using this method:

Arr::sortByKeys(array $array, $keys, bool $assoc = true): array

Here's why:

  • You can sort by any key (also nested like 'key1.key2.key3' or ['k1', 'k2', 'k3'])

  • It works both on associative and not associative arrays ($assoc flag)

  • It doesn't use references - it returns a new sorted array

In your case it would be as simple as:

$sortedArray = Arr::sortByKeys($array, 'order');

This method is a part of this library.

Solution 10 - Php

The working "arrow function" syntax with PHP 7.4 and above:

uasort($yourArray, fn($a, $b) => $a['order'] <=> $b['order']);

pretty print

echo '<pre>';
print_r($yourArray);

Solution 11 - Php

As the accepted answer states you can use:

usort($myArray, function($a, $b) {
    return $a['order'] <=> $b['order'];
});

If you need sort by more than one column, then you would do the following:

usort($myArray, function($a, $b) {
    return [$a['column1'],$a['column2']] <=> [$b['column1'],$b['column2']];
});

This can be extended to any number of columns in your data. This relies on the fact you can directly compare arrays in PHP. In the above example the array would be sorted first by column1 and then by column2. But you can sort by the columns in any order e.g.:

usort($myArray, function($a, $b) {
    return [$a['column2'],$a['column1']] <=> [$b['column2'],$b['column1']];
});

If you need to sort one column ascending and another descending, then swap the descending column to the other side of the operator <=>:

usort($myArray, function($a, $b) {
    return [$a['column1'],$b['column2']] <=> [$b['column1'],$a['column2']];
});

Solution 12 - Php

If anyone needs sort according to a key, the best is to use the below:

usort($array, build_sorter('order'));

function build_sorter($key) {
   return function ($a, $b) use ($key) {
      return strnatcmp($a[$key], $b[$key]);
   };
}

Solution 13 - Php

This solution is for usort() with an easy-to-remember notation for multidimensional sorting. The spaceship operator <=> is used, which is available from PHP 7.

usort($in,function($a,$b){
  return $a['first']   <=> $b['first']  //first asc
      ?: $a['second']  <=> $b['second'] //second asc
      ?: $b['third']   <=> $a['third']  //third desc (a b swapped!)
      //etc
  ;
});

Examples:

$in = [  ['firstname' => 'Anton', 'surname' => 'Gruber', 'birthdate' => '03.08.1967', 'rank' => 3],
  ['firstname' => 'Anna', 'surname' => 'Egger', 'birthdate' => '04.01.1960', 'rank' => 1],
  ['firstname' => 'Paul', 'surname' => 'Mueller', 'birthdate' => '15.10.1971', 'rank' => 2],
  ['firstname' => 'Marie', 'surname' => 'Schmidt ', 'birthdate' => '24.12.1963', 'rank' => 2],
  ['firstname' => 'Emma', 'surname' => 'Mueller', 'birthdate' => '23.11.1969', 'rank' => 2],
];

First task: Order By rank asc, surname asc

usort($in,function($a,$b){
  return $a['rank']      <=> $b['rank']     //first asc
      ?: $a['surname']   <=> $b['surname']  //second asc
  ;
});

Second task: Order By rank desc, surname asc, firstmame asc

usort($in,function($a,$b){
  return $b['rank']      <=> $a['rank']       //first desc
      ?: $a['surname']   <=> $b['surname']    //second asc
      ?: $a['firstname'] <=> $b['firstname']  //third asc
  ;
});

Third task: Order By rank desc, birthdate asc

The date cannot be sorted in this notation. It is converted with strtotime.

usort($in,function($a,$b){
  return $b['rank']      <=> $a['rank']       //first desc
      ?: strtotime($a['birthdate']) <=> strtotime($b['birthdate'])    //second asc
  ;
});

Solution 14 - Php

You could use usort and a user-defined sort function with a callback function:

usort($new, fn($a, $b) => $a['order'] - $b['order']);

TRICK: you could use a > b or a - b or a <=> b for sorting in an ascending order. For a descending order just the swap position of a and b.

Solution 15 - Php

I found this helpful:

    $columns = array_column($data, "order");
    array_multisort($columns, SORT_ASC, $data);

Sort by name ascending

Solution 16 - Php

Let's face it: PHP does not have a simple out-of-the box function to properly handle every array sort scenario.

This routine is intuitive, which means faster debugging and maintenance:

// Automatic population of the array
$tempArray = array();
$annotations = array();
// ... some code
// SQL $sql retrieves result array $result
// $row[0] is the ID, but is populated out of order (comes from
// multiple selects populating various dimensions for the same DATE
// for example
while($row = mysql_fetch_array($result)) {
    $needle = $row[0];
    arrayIndexes($needle);  // Create a parallel array with IDs only
    $annotations[$needle]['someDimension'] = $row[1]; // Whatever
}
asort($tempArray);
foreach ($tempArray as $arrayKey) {
    $dataInOrder = $annotations[$arrayKey]['someDimension'];
    // .... more code
}

function arrayIndexes ($needle) {
    global $tempArray;
    if (!in_array($needle, $tempArray)) {
        array_push($tempArray, $needle);
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionstefView Question on Stackoverflow
Solution 1 - PhpChristian StuderView Answer on Stackoverflow
Solution 2 - Phpo0'.View Answer on Stackoverflow
Solution 3 - PhpTom HaighView Answer on Stackoverflow
Solution 4 - Phpajuchacko91View Answer on Stackoverflow
Solution 5 - PhpJan FabryView Answer on Stackoverflow
Solution 6 - PhpB.KView Answer on Stackoverflow
Solution 7 - PhpGhanshyam NakiyaView Answer on Stackoverflow
Solution 8 - PhpNitrodbzView Answer on Stackoverflow
Solution 9 - PhpMinworkView Answer on Stackoverflow
Solution 10 - Phpdılo sürücüView Answer on Stackoverflow
Solution 11 - PhpGuillermo PhillipsView Answer on Stackoverflow
Solution 12 - PhpZahidView Answer on Stackoverflow
Solution 13 - PhpjspitView Answer on Stackoverflow
Solution 14 - PhpTAHER El MehdiView Answer on Stackoverflow
Solution 15 - PhpDanimalReksView Answer on Stackoverflow
Solution 16 - Phptony gilView Answer on Stackoverflow