Dec 30, 2019 7:00 AM

Sorting multidimensional array by field in PHP

Sorting multidimensional array by field in PHP

In this article I will give an example of how to sort a multidimensional array by field (similar to ORDER BY in a database) in PHP. It is not always possible to properly sort data when retrieving it from the database. Some data can be generated at the PHP level, for example, when calculating the price of a product. After these changes, you may need to sort the resulting data array by a specific field (ascending or descending). Use this function to sort a multidimensional array by field:

function orderBy(array &$array, $sortOrder)
{
    usort($array, function ($a, $b) use ($sortOrder) {
        $result = '';

        $sortOrderArray = explode(',', $sortOrder);
        foreach ($sortOrderArray AS $item) {
            $itemArray = explode(' ', trim($item));
            $field = $itemArray[0];
            $sort = !empty($itemArray[1]) ? $itemArray[1] : '';

            $mix = [$a, $b];
            if (!isset($mix[0][$field]) || !isset($mix[1][$field])) {
                continue;
            }

            if (strtolower($sort) === 'desc') {
                $mix = array_reverse($mix);
            }

            if (is_numeric($mix[0][$field]) && is_numeric($mix[1][$field])) {
                $result .= ceil($mix[0][$field] - $mix[1][$field]);
            } else {
                $result .= strcasecmp($mix[0][$field], $mix[1][$field]);
            }
        }

        return $result;
    });

    return $array;
}

For example, let's take a multidimensional array with the wrong sort

$array = [
    [
        'field_1' => 1,
        'field_2' => 100.58,
        'field_3' => 'C',
    ],
    [
        'field_1' => 1,
        'field_2' => 100.65,
        'field_3' => 'B',
    ],
    [
        'field_1' => 1,
        'field_2' => 100.65,
        'field_3' => 'A',
    ],
    [
        'field_1' => 3,
        'field_2' => 300.15,
        'field_3' => 'E',
    ],
    [
        'field_1' => 2,
        'field_2' => 200.26,
        'field_3' => 'D',
    ],
    [
        'field_1' => 5,
        'field_2' => 500.05,
        'field_3' => 'G',
    ],
    [
        'field_1' => 4,
        'field_2' => 400.74,
        'field_3' => 'F',
    ],
];

and sort it in descending order by field "field_2":

orderBy($array, 'field_2 DESC');

/**
[output]
array (
  0 => 
  array (
    'field_1' => 5,
    'field_2' => 500.05,
    'field_3' => 'G',
  ),
  1 => 
  array (
    'field_1' => 4,
    'field_2' => 400.74,
    'field_3' => 'F',
  ),
  2 => 
  array (
    'field_1' => 3,
    'field_2' => 300.15,
    'field_3' => 'E',
  ),
  3 => 
  array (
    'field_1' => 2,
    'field_2' => 200.26,
    'field_3' => 'D',
  ),
  4 => 
  array (
    'field_1' => 1,
    'field_2' => 100.65,
    'field_3' => 'B',
  ),
  5 => 
  array (
    'field_1' => 1,
    'field_2' => 100.65,
    'field_3' => 'A',
  ),
  6 => 
  array (
    'field_1' => 1,
    'field_2' => 100.58,
    'field_3' => 'C',
  ),
)
 */

You can also sort by multiple fields at once. For example, let's sort the same array in ascending order by field "field_1", then descending order by field "field_2", and then further ascending field "field_3":

orderBy($array, 'field_1 ASC, field_2 DESC, field_3 ASC');

/**
[output]
array (
  0 => 
  array (
    'field_1' => 1,
    'field_2' => 100.65,
    'field_3' => 'A',
  ),
  1 => 
  array (
    'field_1' => 1,
    'field_2' => 100.65,
    'field_3' => 'B',
  ),
  2 => 
  array (
    'field_1' => 1,
    'field_2' => 100.58,
    'field_3' => 'C',
  ),
  3 => 
  array (
    'field_1' => 2,
    'field_2' => 200.26,
    'field_3' => 'D',
  ),
  4 => 
  array (
    'field_1' => 3,
    'field_2' => 300.15,
    'field_3' => 'E',
  ),
  5 => 
  array (
    'field_1' => 4,
    'field_2' => 400.74,
    'field_3' => 'F',
  ),
  6 => 
  array (
    'field_1' => 5,
    'field_2' => 500.05,
    'field_3' => 'G',
  ),
)
 */

Other articles