How To Sort A Multi-Dimensional Array By Value In PHP?

Published October 1, 2024

Problem: Sorting Multi-Dimensional Arrays in PHP

Sorting multi-dimensional arrays by value in PHP can be hard. This task involves organizing complex data structures with nested arrays based on set criteria, which isn't always easy using PHP's built-in sorting functions.

PHP's Built-in Sorting Functions for Multi-Dimensional Arrays

The usort() Function

The usort() function in PHP sorts arrays, including multi-dimensional ones. It lets you define a custom comparison function to order elements.

The basic syntax of usort() is:

usort($array, $comparison_function);

$array is the array to sort, and $comparison_function compares two elements.

Using usort() for multi-dimensional arrays offers these benefits:

  • Flexibility: Sort based on any criteria within nested arrays.
  • Custom logic: Implement sorting rules for your needs.
  • Multiple keys: Sort based on multiple keys or nested elements.

Example: Sorting a multi-dimensional array by a specific key

$people = [
    ['name' => 'Alice', 'age' => 30],
    ['name' => 'Bob', 'age' => 25],
    ['name' => 'Charlie', 'age' => 35]
];

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

print_r($people);

This example sorts the $people array by age in ascending order.

The uasort() Function

The uasort() function is like usort(), but it keeps the key associations of the original array. This is useful when you need to keep the original keys after sorting.

Use uasort() instead of usort() when:

  • You need to keep the original array keys intact.
  • Your array uses string keys or non-sequential numeric keys.
  • The key-value relationship is important for your data structure.

The syntax for uasort() is the same as usort():

uasort($array, $comparison_function);

By using uasort(), you can sort your multi-dimensional array while keeping the key associations. This is useful when working with associative arrays where the keys have meaning or when you need to reference specific elements by their original keys after sorting.

Tip: Preserving key associations with uasort()

When using uasort(), remember that it maintains the original key-value pairs. This can be particularly useful when dealing with database results or when the array keys represent unique identifiers. Always use uasort() instead of usort() when you need to keep the original array structure intact while sorting.

Implementing Custom Sorting Logic

Creating a Comparison Function

A custom comparison function lets you set sorting rules for your multi-dimensional array. This function takes two elements as parameters and returns a value indicating their order.

To create a comparison function:

  1. Define a function with two parameters ($a and $b).
  2. Compare the values of interest in these elements.
  3. Return -1 if $a comes before $b, 1 if $b comes before $a, or 0 if they are equal.

Example of a comparison function that sorts by age:

function compareAge($a, $b) {
    return $a['age'] - $b['age'];
}

When handling different data types in the array, you may need to use type-specific comparison methods:

function compareItems($a, $b) {
    if (is_string($a['value']) && is_string($b['value'])) {
        return strcmp($a['value'], $b['value']);
    }
    return $a['value'] - $b['value'];
}

To sort based on multiple criteria, you can create a more complex comparison function:

function compareMultiple($a, $b) {
    $result = $a['priority'] - $b['priority'];
    if ($result == 0) {
        $result = strcmp($a['name'], $b['name']);
    }
    return $result;
}

Tip: Handling Case-Insensitive Sorting

When sorting strings, you might want to perform a case-insensitive comparison. Use the strcasecmp() function instead of strcmp() to achieve this:

function compareCaseInsensitive($a, $b) {
    return strcasecmp($a['name'], $b['name']);
}

Using Anonymous Functions for Sorting

Anonymous functions, or closures, are functions without a name. They are useful for creating inline functions for sorting operations.

To use an anonymous function for sorting:

  1. Define the function directly in the usort() or uasort() call.
  2. Use the function keyword followed by the parameters and function body.

Example:

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

Benefits of using anonymous functions for sorting:

  1. Concise code: You can define the sorting logic inline, making the code more readable.
  2. Scope access: Anonymous functions can access variables from the parent scope.
  3. One-time use: They are ideal for sorting logic that you won't reuse elsewhere.

Example of sorting with an anonymous function that accesses a variable from the parent scope:

$sortKey = 'age';
usort($people, function($a, $b) use ($sortKey) {
    return $a[$sortKey] - $b[$sortKey];
});

This approach allows for dynamic sorting based on a variable defined outside the sorting function.

Advanced Sorting Techniques

Sorting with the Spaceship Operator

The spaceship operator (<=>) is a comparison operator in PHP 7. It simplifies comparisons by returning -1, 0, or 1 based on the relationship between two values.

To use the spaceship operator for sorting:

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

This operator works with numbers and strings. It makes sorting code shorter and easier to read.

The spaceship operator can handle multi-level sorting:

usort($array, function($a, $b) {
    return $a['priority'] <=> $b['priority'] ?: $a['name'] <=> $b['name'];
});

The spaceship operator may be slightly slower than direct comparison, but for most uses, this difference is small.

Tip: Reverse Sorting with Spaceship Operator

To sort in descending order using the spaceship operator, simply negate the result:

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

This reverses the sorting order without changing the logic of your comparison.

Arrow Functions for Compact Sorting Code

Arrow functions, added in PHP 7.4, offer a shorter syntax for simple functions. They work well for sorting operations.

To use an arrow function for sorting:

usort($array, fn($a, $b) => $a['value'] <=> $b['value']);

Arrow functions make sorting logic shorter by reducing extra code. They work best for short, single-expression comparisons.

Comparing arrow functions to regular anonymous functions:

  1. Arrow functions:

    usort($array, fn($a, $b) => $a['value'] <=> $b['value']);
  2. Regular anonymous functions:

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

Arrow functions are shorter but have limits. They can't have multiple expressions or use the 'use' keyword to get variables from the parent scope. For complex sorting logic, regular anonymous functions might work better.

Tip: Combining Arrow Functions and Spaceship Operator

For the shortest sorting code, combine arrow functions with the spaceship operator:

usort($array, fn($a, $b) => $a['priority'] <=> $b['priority'] ?: $a['name'] <=> $b['name']);

This method gives you a clear, readable solution for multi-level sorting in one line of code.