How do I sort a multidimensional array by one of t

2020-01-24 09:44发布

Suppose I have an array that mimics a database table. Each array element represents a row, and within each row is another array that contains the field names and values.

Array
(
    [0] => Array
        (
            [name] => 'Sony TV'
            [price] => 600.00
        )

    [1] => Array
        (
            [name] => 'LG TV'
            [price] => 350.00
        )

    [2] => Array
        (
            [name] => 'Samsung TV'
            [price] => 425.00
        )  
}

What I want to do is sort the rows (outer array elements) by price. Below is an example of what I want to achieve:

Array
(
    [0] => Array
        (
            [name] => 'LG TV'
            [price] => 350.00
        )

    [1] => Array
        (
            [name] => 'Samsung TV'
            [price] => 425.00
        )

    [2] => Array
        (
            [name] => 'Sony TV'
            [price] => 600.00
        )        
}

As you can see, I don't need to preserve the keys of the outer array.

8条回答
smile是对你的礼貌
2楼-- · 2020-01-24 10:04

This is basically the same as the accepted answer, but a couple of new features have been added to PHP over the years to make it more convenient to use usort for this.

$column = 'price';
usort($table, function($a, $b) use ($column) {
    return $a[$column] <=> $b[$column];
});

You can now use an anonymous function for the comparison callback (as of PHP 5.3), and PHP 7 introduced the combined comparison operator (<=>), which allows you to reduce the comparison logic

if ($a['price'] == $b['price']) return 0;
return ($a['price'] > $b['price']) ? 1 : -1;

to a single expression

return $a[$column] <=> $b[$column];
查看更多
forever°为你锁心
3楼-- · 2020-01-24 10:05

You can create a function yourself like the one below

private function orderArrayBycolumn($array, $column){

    $newArray = [];
    foreach ($array as $key => $value) {
        $newArray[$value[$column]] = $value;
    }

    $array = [];

    ksort($newArray);

    foreach ($newArray as $key => $value) {
        $array[] = $value;
    }      

    return $array;
}
查看更多
淡お忘
4楼-- · 2020-01-24 10:11

You need to use usort, a function that sorts arrays via a user defined function. Something like:

function cmp($a, $b)
{
    if ($a["price"] == $b["price"]) {
        return 0;
    }
    return ($a["price"] < $b["price"]) ? -1 : 1;
}

usort($yourArray,"cmp")
查看更多
三岁会撩人
5楼-- · 2020-01-24 10:14

You can use usort():

function sort($a, $b) {
    if ($a['price'] == $b['price']) return 0;
    return ($a['price'] > $b['price']) ? 1 : -1;
}

usort($array, 'sort');

Even better if you create a class like this to reuse the code:

class FieldSorter {
    public $field;

    function __construct($field) {
        $this->field = $field;
    }

    function cmp($a, $b) {
        if ($a[$this->field] == $b[$this->field]) return 0;
        return ($a[$this->field] > $b[$this->field]) ? 1 : -1;
    }
}

$sorter = new FieldSorter('price');    
usort($array, array($sorter, "cmp"));

This way, you can easily sort by other fields.

And although you said the the keys of the outer array don't have to be preserved you can easily achieve this by using uasort() instead of usort.

查看更多
\"骚年 ilove
6楼-- · 2020-01-24 10:14

You can use the usort function with a callback

http://www.php.net/manual/en/function.usort.php

查看更多
▲ chillily
7楼-- · 2020-01-24 10:16

I just want to make a couple additions...

@rf1234's answer is probably what I would go for (because I read somewhere that array_multisort() outperforms usort(), but I haven't personally benchmarked them), but the sorting direction does not need to be declared because the default direction is ASC.

Code: (Demo)

$column = 'price';
array_multisort(array_column($array, $column), $array);
var_export($array);

@Don'tPanic's answer using usort() with the spaceship operator is also attractive. From PHP7.4, the syntax can be reduced and the use() expression can be removed by using arrow function syntax. This technique allows $column to freely enter the function scope without use().

Code: (Demo)

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

I recommend either of these correct, efficient, direct solutions.

查看更多
登录 后发表回答