Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中,如何按内部数组的一个字段对多维数组进行排序?_Php_Arrays_Sorting_Multidimensional Array - Fatal编程技术网

在PHP中,如何按内部数组的一个字段对多维数组进行排序?

在PHP中,如何按内部数组的一个字段对多维数组进行排序?,php,arrays,sorting,multidimensional-array,Php,Arrays,Sorting,Multidimensional Array,假设我有一个模拟数据库表的数组。每个数组元素表示一行,每行中都有另一个包含字段名和值的数组 Array ( [0] => Array ( [name] => 'Sony TV' [price] => 600.00 ) [1] => Array ( [name] => 'LG TV' [price] =>

假设我有一个模拟数据库表的数组。每个数组元素表示一行,每行中都有另一个包含字段名和值的数组

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
        )  
}
我想做的是按价格对行(外部数组元素)排序。下面是我想要实现的一个例子:

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
        )        
}

如您所见,我不需要保留外部数组的键。

您可以将usort函数与回调一起使用

您可以使用:

如果创建这样的类以重用代码,则效果更好:

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"));
这样,您就可以轻松地按其他字段进行排序

尽管您说过外部数组的键不必保留,但您可以通过使用一个通过用户定义函数对数组进行排序的函数,而不是您需要使用的
usort
,轻松实现这一点。比如:

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

usort($yourArray,"cmp")
函数cmp($a,$b)
{
如果($a[“价格”]==b[“价格”]){
返回0;
}
回报($a[“价格”]<$b[“价格”])?-1:1;
}
usort($yourArray,“cmp”)

这个问题有点老了,但将在这里留下答案供将来使用

从 函数我们可以使用下面的代码

    $data= [['volume' => 67, 'edition' => 2],['volume' => 85, 'edition' => 6],...];
foreach ($data as $key => $row) {
    $volume[$key]  = $row['volume'];
    $edition[$key] = $row['edition'];
}
array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data);
上面是用于数据的静态排序,您可以手动更改排序列

为更动态和稳健的例子考虑如下; 假设我有以下数据

$data   = [[1, 'Amanda', 'Wright', 'awright0@usnews.com', 'Female', '135.114.57.89', 31237],
           [2, 'Theresa', 'Larson', 'tlarson1@51.la', 'Female', '207.108.96.210', 91011],
           [3, 'Walter', 'Kennedy', 'wkennedy2@baidu.com', 'Male', '199.147.223.56', 50114],
           [4, 'Andrea', 'Richards', 'arichards3@google.nl', 'Female', '230.195.124.95', 76489],
           [5, 'Carol', 'Jones', 'cjones4@elegantthemes.com', 'Female', '250.197.111.90', 56501],
           [6, 'Alice', 'Freeman', 'afreeman5@elegantthemes.com', 'Female', '52.195.252.131', 77170],
           [7, 'Gerald', 'Fisher', 'gfisher6@slashdot.org', 'Male', '81.2.22.62', 75625],....]
如果需要对上述数组数据进行开箱排序,那么可以使用语法在数组中设置排序顺序

 $qTable[$index]=$sort_order;
E.g. $qTable=[1=>'asc',4=>'desc',3=>'asc'];
这意味着对第1列ASC、第4列DESC和第3列ASC进行排序。 然后,我们可以使用下面的函数对多维数据库数据进行排序

   function sortMulti($data, $orders)
    {
        $args = [];
        foreach ($data as $key => $row) {
            foreach ($orders as $index => $order) {
                if (!isset($row[$index])) continue; //Ignore if column does'nt exist
                $args[$index]['d'][$key] = $row[$index]; //Get all values within the column
                $args[$index]['o']       = 'desc' == strtolower($order) ? SORT_DESC : SORT_ASC; //Get the Sort order 'ASC' is the default
            }
        }
        $p = [];
//Below we need to organize our entries as arguments for array_multisort
        foreach ($args as $arg) {
            $p[] = $arg['d'];
            $p[] = $arg['o'];
//Below we need to check if column contains only numeric or not.
//If all values are numeric, then we use numeric sort flag, otherwise NATURAL
//Manipulate for more conditions supported
            $p[] = count($arg['d']) == count(array_filter($arg['d'], 'is_numeric')) ? SORT_NUMERIC : SORT_NATURAL;
        }
        $p[] = &$data; //Pass by reference
        call_user_func_array('array_multisort', $p); //Call Php's own multisort with parameters in required order.
        return $data; //Our final array sorted.
    }
然后我们可以使用它如下

$data=[[...],[...],...];
$order=[1=>'asc',4=>'desc',3=>'asc'];

$sorted=sortMulti($data,$order);
对于键值数组数据
,例如$data=[[c1'=>1212,'c2'=>mynames'],…]
使用顺序为
$order=['c1'=>'desc','c10'=>'asc']

我用1000条记录的数组测试了上述内容。
希望它能帮助别人。

您可以自己创建一个函数,如下所示

私有函数orderArrayBycolumn($array,$column){

这只是一个班轮

array_multisort( array_column($yourArray, "price"), SORT_ASC, $yourArray );
您也可以在这里找到:

在该手册页面上搜索“array_column”

2020年12月1日的更新:

正如@Tyler V.在他的评论中提到的,这种语法可能会导致新的PHP7版本中出现“只能通过引用传递变量”的错误。为了避免这些错误,您需要将一行代码更改为两行代码,不幸的是:

$col = array_column( $yourArray, "price" );
array_multisort( $col, SORT_ASC, $yourArray );

这与公认的答案基本相同,但多年来PHP增加了一些新功能,使使用
usort
更方便

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

return $a[$column] <=> $b[$column];
返回$a[$column]$b[$column];

我只想做一些补充

@rf1234的答案可能是我想要的(因为我在某个地方读到
array\u multisort()
优于
usort()
,但我个人没有对它们进行基准测试),但排序方向不需要声明,因为默认方向是ASC

代码:()


@Don'tPanic使用spaceship操作符的
usort()
的回答也很有吸引力。从PHP7.4开始,可以使用箭头函数语法减少语法,删除
use()
表达式。这种技术允许
$column
自由进入函数范围,而无需
use()

代码:()

$column='price';
usort($array,fn($a,$b)=>a[$column]$b[$column]);
var_导出($数组);

我推荐这两种正确、高效、直接的解决方案。

注意:如果您的数据来自数据库,请在选择时使用数据库的排序方法。@DisgrudedCoat它不是来自数据库。我只是以它为例。它实际上来自第三方XML。答案很好。IMHO,这里的前两个答案,同时获取工作完成了,实际上似乎是在重新发明轮子。然而,请注意,
array\u column
仅在PHP>=5.5中可用,这是正确的Ifedi。无论如何,人们不应该使用旧的PHP版本。即使PHP7.0现在已经不推荐使用了……最好使用PHP7.2或7.3
SORT\u ASC
是默认的排序方向,并且可以忽略。在以后的版本中这将触发“只能通过引用传递变量”的错误。要解决此问题,请将数组_column()的输出移动到一个变量,然后将该变量传递到数组_multisort()“循环,然后排序,然后循环”不是一个有吸引力或有效的建议。你为什么要费心重新发布user2182349的答案?与其他答案相比,此链接唯一的答案看起来不够成熟,不太可能对研究人员有所帮助。无评论DVs从未强迫我删除正确且信息丰富的答案。
$column = 'price';
usort($table, function($a, $b) use ($column) {
    return $a[$column] <=> $b[$column];
});
if ($a['price'] == $b['price']) return 0;
return ($a['price'] > $b['price']) ? 1 : -1;
return $a[$column] <=> $b[$column];
$column = 'price';
array_multisort(array_column($array, $column), $array);
var_export($array);
$column = 'price';
usort($array, fn($a, $b) => $a[$column] <=> $b[$column]);
var_export($array);