array_multisort

(PHP 4, PHP 5, PHP 7, PHP 8)

array_multisort对多个或多维数组进行排序

描述

array_multisort(
    array &$array1,
    mixed $array1_sort_order = SORT_ASC,
    mixed $array1_sort_flags = SORT_REGULAR,
    mixed ...$rest
): bool

array_multisort() 可用于一次性对多个数组进行排序,或按一个或多个维度对多维数组进行排序。

关联 (string) 键将被保留,但数字键将被重新索引。

注意:

如果两个成员比较相等,则它们将保留其原始顺序。在 PHP 8.0.0 之前,它们在排序数组中的相对顺序是未定义的。

注意:

将数组的内部指针重置为第一个元素。

参数

array1

要排序的 array

array1_sort_order

用于对上一个 array 参数进行排序的顺序。可以是 SORT_ASC 以升序排序或 SORT_DESC 以降序排序。

此参数可以与 array1_sort_flags 交换或完全省略,在这种情况下假定为 SORT_ASC

array1_sort_flags

对上一个 array 参数进行排序的选项

排序类型标志

此参数可以与 array1_sort_order 交换或完全省略,在这种情况下假定为 SORT_REGULAR

rest

更多数组,可以选择后面跟排序顺序和标志。仅比较与之前数组中等效元素相对应的元素。换句话说,排序是按字典顺序的。

返回值

成功时返回 true,失败时返回 false

示例

示例 #1 对多个数组进行排序

<?php
$ar1
= array(10, 100, 100, 0);
$ar2 = array(1, 3, 2, 4);
array_multisort($ar1, $ar2);

var_dump($ar1);
var_dump($ar2);
?>

在这个示例中,排序后,第一个数组将包含 0、10、100、100。第二个数组将包含 4、1、2、3。第二个数组中对应于第一个数组中相同项(100 和 100)的项也进行了排序。

array(4) {
  [0]=> int(0)
  [1]=> int(10)
  [2]=> int(100)
  [3]=> int(100)
}
array(4) {
  [0]=> int(4)
  [1]=> int(1)
  [2]=> int(2)
  [3]=> int(3)
}

示例 #2 对多维数组进行排序

<?php
$ar
= array(
array(
"10", 11, 100, 100, "a"),
array(
1, 2, "2", 3, 1)
);
array_multisort($ar[0], SORT_ASC, SORT_STRING,
$ar[1], SORT_NUMERIC, SORT_DESC);
var_dump($ar);
?>

在这个示例中,排序后,第一个数组将变为“10”、100、100、11、“a”(它按升序作为字符串排序)。第二个将包含 1、3、“2”、2、1(按数字排序,降序排序)。

array(2) {
  [0]=> array(5) {
    [0]=> string(2) "10"
    [1]=> int(100)
    [2]=> int(100)
    [3]=> int(11)
    [4]=> string(1) "a"
  }
  [1]=> array(5) {
    [0]=> int(1)
    [1]=> int(3)
    [2]=> string(1) "2"
    [3]=> int(2)
    [4]=> int(1)
  }
}

示例 #3 对数据库结果进行排序

对于此示例,data 数组中的每个元素代表表中的一行。这种类型的数据集是数据库记录的典型数据。

示例数据

volume | edition
-------+--------
    67 |       2
    86 |       1
    85 |       6
    98 |       2
    86 |       6
    67 |       7

数据作为数组,称为 data。这通常(例如)通过使用 mysqli_fetch_assoc() 进行循环来获得。

<?php
$data
[] = array('volume' => 67, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 1);
$data[] = array('volume' => 85, 'edition' => 6);
$data[] = array('volume' => 98, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 6);
$data[] = array('volume' => 67, 'edition' => 7);
?>

在这个示例中,我们将按 volume 降序、edition 升序进行排序。

我们有一个行数组,但 array_multisort() 需要一个列数组,因此我们使用以下代码来获取列,然后执行排序。

<?php
// 获取列列表
foreach ($data as $key => $row) {
$volume[$key] = $row['volume'];
$edition[$key] = $row['edition'];
}

// 可以使用 array_column() 代替以上代码
$volume = array_column($data, 'volume');
$edition = array_column($data, 'edition');

// 按 volume 降序,edition 升序排序数据
// 添加 $data 作为最后一个参数,按公共键排序
array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data);
?>

现在数据集已排序,将如下所示

volume | edition
-------+--------
    98 |       2
    86 |       1
    86 |       6
    85 |       6
    67 |       2
    67 |       7

示例 #4 不区分大小写的排序

SORT_STRINGSORT_REGULAR 都是区分大小写的,以大写字母开头的字符串将排在以小写字母开头的字符串之前。

要执行不区分大小写的排序,请强制排序顺序由原始数组的小写副本确定。

<?php
$array
= array('Alpha', 'atomic', 'Beta', 'bank');
$array_lowercase = array_map('strtolower', $array);

array_multisort($array_lowercase, SORT_ASC, SORT_STRING, $array);

print_r($array);
?>

上面的例子将输出

Array
(
    [0] => Alpha
    [1] => atomic
    [2] => bank
    [3] => Beta
)

参见

添加注释

用户贡献的注释 42 条注释

221
jimpoz at jimpoz dot com
13 年前
我想到了一种对数据库式结果进行排序的简单方法。这与示例 3 相同,但它会为您处理创建这些中间数组,然后再将控制权传递给 array_multisort()。

<?php
function array_orderby()
{
$args = func_get_args();
$data = array_shift($args);
foreach (
$args as $n => $field) {
if (
is_string($field)) {
$tmp = array();
foreach (
$data as $key => $row)
$tmp[$key] = $row[$field];
$args[$n] = $tmp;
}
}
$args[] = &$data;
call_user_func_array('array_multisort', $args);
return
array_pop($args);
}
?>

现在排序后的数组位于函数的返回值中,而不是通过引用传递。

<?php
$data
[] = array('volume' => 67, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 1);
$data[] = array('volume' => 85, 'edition' => 6);
$data[] = array('volume' => 98, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 6);
$data[] = array('volume' => 67, 'edition' => 7);

// 传递数组,然后是列名和排序标志
$sorted = array_orderby($data, 'volume', SORT_DESC, 'edition', SORT_ASC);
?>
73
matt at bosc dot io
8 年前
使用 array_column 对多维数组按键进行排序的单行函数

<?php

array_multisort
(array_column($array, 'key'), SORT_DESC, $array);

?>
91
cagret at gmail dot com
15 年前
一种更直观的方法是使用 array_msort() 在一行代码中对多维数组进行排序,您无需将原始数组划分为按列数组

<?php

$arr1
= array(
array(
'id'=>1,'name'=>'aA','cat'=>'cc'),
array(
'id'=>2,'name'=>'aa','cat'=>'dd'),
array(
'id'=>3,'name'=>'bb','cat'=>'cc'),
array(
'id'=>4,'name'=>'bb','cat'=>'dd')
);

$arr2 = array_msort($arr1, array('name'=>SORT_DESC, 'cat'=>SORT_ASC));

debug($arr1, $arr2);

arr1:
0:
id: 1 (int)
name: aA (string:2)
cat: cc (string:2)
1:
id: 2 (int)
name: aa (string:2)
cat: dd (string:2)
2:
id: 3 (int)
name: bb (string:2)
cat: cc (string:2)
3:
id: 4 (int)
name: bb (string:2)
cat: dd (string:2)
arr2:
2:
id: 3 (int)
name: bb (string:2)
cat: cc (string:2)
3:
id: 4 (int)
name: bb (string:2)
cat: dd (string:2)
0:
id: 1 (int)
name: aA (string:2)
cat: cc (string:2)
1:
id: 2 (int)
name: aa (string:2)
cat: dd (string:2)

function
array_msort($array, $cols)
{
$colarr = array();
foreach (
$cols as $col => $order) {
$colarr[$col] = array();
foreach (
$array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); }
}
$eval = 'array_multisort(';
foreach (
$cols as $col => $order) {
$eval .= '$colarr[\''.$col.'\'],'.$order.',';
}
$eval = substr($eval,0,-1).');';
eval(
$eval);
$ret = array();
foreach (
$colarr as $col => $arr) {
foreach (
$arr as $k => $v) {
$k = substr($k,1);
if (!isset(
$ret[$k])) $ret[$k] = $array[$k];
$ret[$k][$col] = $array[$k][$col];
}
}
return
$ret;

}

?>
47
Robert C
10 年前
您好!

我希望看到将以下代码片段添加到 http://nl3.php.net/array_multisort 中。

目的:根据一些键对二维数组进行排序

该函数的优势
- 使用 PHP 的 `array_multisort` 函数进行排序;
- 它为您准备了数组(`array_multisort` 需要);
- 允许排序标准作为单独的数组传递(可以使用排序顺序和标志);
- 轻松设置/覆盖字符串排序方式(不区分大小写而不是区分大小写,这是 PHP 的默认排序方式);
- 性能卓越

function MultiSort($data, $sortCriteria, $caseInSensitive = true)
{
if( !is_array($data) || !is_array($sortCriteria))
return false;
$args = array();
$i = 0;
foreach($sortCriteria as $sortColumn => $sortAttributes)
{
$colList = array();
foreach ($data as $key => $row)
{
$convertToLower = $caseInSensitive && (in_array(SORT_STRING, $sortAttributes) || in_array(SORT_REGULAR, $sortAttributes));
$rowData = $convertToLower ? strtolower($row[$sortColumn]) : $row[$sortColumn];
$colLists[$sortColumn][$key] = $rowData;
}
$args[] = &$colLists[$sortColumn];

foreach($sortAttributes as $sortAttribute)
{
$tmp[$i] = $sortAttribute;
$args[] = &$tmp[$i];
$i++;
}
}
$args[] = &$data;
call_user_func_array('array_multisort', $args);
return end($args);
}

用法

// 用随机测试数据填充数组
define('MAX_ITEMS', 15);
define('MAX_VAL', 20);
for($i=0; $i < MAX_ITEMS; $i++)
$data[] = array('field1' => rand(1, MAX_VAL), 'field2' => rand(1, MAX_VAL), 'field3' => rand(1, MAX_VAL) );

// 设置排序标准(添加任意数量的字段)
$sortCriteria =
array('field1' => array(SORT_DESC, SORT_NUMERIC),
'field3' => array(SORT_DESC, SORT_NUMERIC)
);

// 像这样调用它
$sortedData = MultiSort($data, $sortCriteria, true);
22
nick ([AT]) nickyost ([DOT]) com
12 年前
`usort` 函数几乎不需要任何工作就可以用于对多维数组进行排序,方法是使用自定义排序函数中的各个值。

此函数传递整个子元素,即使它不是字符串。如果它是一个数组,例如在多维数组中,它将把整个子数组作为参数传递。

因此,做一些优雅的事情,比如这样

<?php
// 对多维数组进行排序
usort($results, "custom_sort");
// 定义自定义排序函数
function custom_sort($a,$b) {
return
$a['some_sub_var']>$b['some_sub_var'];
}
?>

这在 4 行代码中做到了其他函数需要 40 到 50 行才能完成的事情。这不需要您创建临时数组或任何其他东西。对我来说,这是比这个函数更可取的解决方案。

希望对您有所帮助!
7
frank at overdrunk dot net
15 年前
我有一个函数用来对二维数组进行排序,我想使用一列来排序数组,这列通常包含数值,但也包含字符串。

假设我们有这个数组

数组 (
[0] => 数组 ( "name" = "12000" ),
[1] => 数组 ( "name" = "113" ),
[2] => 数组 ( "name" = "test 01" ),
[3] => 数组 ( "name" = "15000 tests" ),
[4] => 数组 ( "name" = "45" ),
[5] => 数组 ( "name" = "350" ),
[6] => 数组 ( "name" = "725" ),
[7] => 数组 ( "name" = "hello" )
}

SORT_STRING 将会返回给我这个

数组 ( // 数值没有正确排序
[0] => 数组 ( "name" = "113" ),
[1] => 数组 ( "name" = "12000" ),
[2] => 数组 ( "name" = "15000 tests" ),
[3] => 数组 ( "name" = "350" ),
[4] => 数组 ( "name" = "45" ),
[5] => 数组 ( "name" = "725" ),
[6] => 数组 ( "name" = "hello" ),
[7] => 数组 ( "name" = "test 01" )
}

SORT_NUMERIC 将会返回给我这个

数组 ( // 字符串值没有排序,只是保持相同的顺序
[0] => 数组 ( "name" = "test 01" ),
[1] => 数组 ( "name" = "hello" ),
[2] => 数组 ( "name" = "45" ),
[3] => 数组 ( "name" = "113" ),
[4] => 数组 ( "name" = "350" ),
[5] => 数组 ( "name" = "725" ),
[6] => 数组 ( "name" = "12000" ),
[7] => 数组 ( "name" = "15000 tests" ),
}

因此,我创建了这段混合代码,它结合了两种方法的优点,通过将两种方式排序的内容合并起来,根据字符串的第一个字符进行排序。

<?php
/**
* 根据指定的列对数组进行排序
* 参数:数组 $table
* 字符串 $colname
* 布尔值 $numeric
**/
function sort_col($table, $colname) {
$tn = $ts = $temp_num = $temp_str = array();
foreach (
$table as $key => $row) {
if(
is_numeric(substr($row[$colname], 0, 1))) {
$tn[$key] = $row[$colname];
$temp_num[$key] = $row;
}
else {
$ts[$key] = $row[$colname];
$temp_str[$key] = $row;
}
}
unset(
$table);

array_multisort($tn, SORT_ASC, SORT_NUMERIC, $temp_num);
array_multisort($ts, SORT_ASC, SORT_STRING, $temp_str);
return
array_merge($temp_num, $temp_str);
}
?>

它将会返回类似于这个的结果

数组 (
[2] => 数组 ( "name" = "45" ),
[3] => 数组 ( "name" = "113" ),
[4] => 数组 ( "name" = "350" ),
[5] => 数组 ( "name" = "725" ),
[6] => 数组 ( "name" = "12000" ),
[7] => 数组 ( "name" = "15000 tests" ),
[1] => 数组 ( "name" = "hello" ),
[0] => 数组 ( "name" = "test 01" ),
}
3
lingtalfi
3 years ago
对于数据库式的排序,我提供一点建议

<?php
/**
* RowsSortHelperTool 类。
*/
class RowsSortHelperTool
{

/**
* 根据给定的排序规则对给定的数组进行排序。
*
* 排序规则参数是一个字段 => 方向 的数组,
*
* 其中:
*
* - 字段:字符串,用于对行进行排序的属性名称
* - 方向:字符串(asc|desc),排序方向
*
*
* @param 数组 $rows
* @param 数组 $sorts
* @return 数组
*/
public static function sort(array &$rows, array $sorts)
{

$args = [];

foreach (
$sorts as $field => $direction) {
$col = array_column($rows, $field);
$args[] = $col;

if (
'asc' === $direction) {
$args[] = SORT_ASC;
} else {
$args[] = SORT_DESC;
}
}
$args[] = &$rows;
call_user_func_array("array_multisort", $args);
}
}

?>

像这样使用它

<?php
$data
[] = array('volume' => 67, 'edition' => 2, 'mine' => 5);
$data[] = array('volume' => 86, 'edition' => 1, 'mine' => 5);
$data[] = array('volume' => 85, 'edition' => 6, 'mine' => 5);
$data[] = array('volume' => 98, 'edition' => 2, 'mine' => 5);
$data[] = array('volume' => 86, 'edition' => 6, 'mine' => 4);
$data[] = array('volume' => 86, 'edition' => 6, 'mine' => 5);
$data[] = array('volume' => 67, 'edition' => 7, 'mine' => 5);

RowsSortHelperTool::sort($data, [
'volume' => 'desc',
'edition' => 'asc',
'mine' => 'desc',
]);

az($data);

?>

将会显示类似于这个的结果

数组(7) {
[0] => 数组(3) {
["volume"] => 整数(98)
["edition"] => 整数(2)
["mine"] => 整数(5)
}
[1] => 数组(3) {
["volume"] => 整数(86)
["edition"] => 整数(1)
["mine"] => 整数(5)
}
[2] => 数组(3) {
["volume"] => 整数(86)
["edition"] => 整数(6)
["mine"] => 整数(5)
}
[3] => 数组(3) {
["volume"] => 整数(86)
["edition"] => 整数(6)
["mine"] => 整数(4)
}
[4] => 数组(3) {
["volume"] => 整数(85)
["edition"] => 整数(6)
["mine"] => 整数(5)
}
[5] => 数组(3) {
["volume"] => 整数(67)
["edition"] => 整数(2)
["mine"] => 整数(5)
}
[6] => 数组(3) {
["volume"] => 整数(67)
["edition"] => 整数(7)
["mine"] => 整数(5)
}
}
16
zequez at gmail dot com
14 years ago
我发现对整个多维数组根据其一个元素进行排序最简单的方法

<?php
$multiArray
= Array(
Array(
"id" => 1, "name" => "Defg"),
Array(
"id" => 2, "name" => "Abcd"),
Array(
"id" => 3, "name" => "Bcde"),
Array(
"id" => 4, "name" => "Cdef"));
$tmp = Array();
foreach(
$multiArray as &$ma)
$tmp[] = &$ma["name"];
array_multisort($tmp, $multiArray);
foreach(
$multiArray as &$ma)
echo
$ma["name"]."<br/>";

/* 输出
Abcd
Bcde
Cdef
Defg
*/
?>

^-^
10
RWC
18 years ago
这是 AlberT 函数的简化版本。

很多时候你会得到一个像这样的数组

$test[0]['name']='Peter';
$test[0]['points']=1;

$test[1]['name']='Mike';
$test[1]['points']=5;

$test[2]['name']='John';
$test[2]['points']=2;

你只想对第二维的索引进行排序,例如上面的例子中的 "points"。

你可以使用下面的函数并像这样调用它

$test = multi_sort($test, $key = 'points');

函数 multi_sort($array, $akey)
{
函数 compare($a, $b)
{
全局 $key;
返回 strcmp($a[$key], $b[$key]);
}
usort($array, "compare");
返回 $array;
}

注意:为了能够在 compare 函数中使用 $key,它不能简单地作为参数传递。它必须在 compare() 函数外部声明为全局变量并进行设置。
1
faugeron dot loic at gmail dot com
8 年前
改进示例 #3(排序数据库结果):使用 <?php array_column ?>(PHP >= 5.5)和 <?php call_user_func_array ?>,可以构建排序(按一个或多个字段排序)。

<?php

$data
= [
[
'id' => '168ac7f8-c918-4e99-90ee-5d7590fe61ce',
'name' => 'Arthur Dent',
],
[
'id' => 'e3ad45ee-7cae-4cca-bd7b-2eb6b57b6457',
'name' => 'Ford Prefect',
],
[
'id' => 'a426aef2-19e2-412a-8339-5458cf6ae416',
'name' => 'Trillian Astra',
],
];
$sortings = [
[
'field' => 'id',
'direction' => SORT_DESC,
],
];

$args = [];
$key = 0;
foreach (
$sortings as $sorting) {
$args[$key] = array_column($data, $sorting['field']);
$args[$key + 1] = $sorting['direction'];
$key += 2;
}
$args[] = $data;
call_user_func_array('array_multisort', $args);

// $data 现在按 ID 降序排序。
?>
1
nospam at nospam dot com
8 年前
一种超级简单的方法,可以对带键的多维数组进行排序,同时保留所有关联键,包括数字键!

如果排序值相等,则保留原始多维数组的顺序。

<?php
// 对多维数组进行排序,按子数组的值排序,同时保留所有键,如果排序值匹配,则保留原始顺序
function maSort($ma = '', $sortkey = '', $sortorder = 1) { // sortorder: 1=升序,2=降序
if ($ma && is_array($ma) && $sortkey) { // 确认输入
foreach ($ma as $k=>$a) $temp["$a[$sortkey]"][$k] = $a; // 带排序值的临时 ma,引号将键转换为字符串,以防数字浮点数
if ($sortorder == 2) { // 降序
krsort($temp);
} else {
// 升序
ksort($temp);
}
$newma = array(); // 用于添加的空白输出多维数组
foreach ($temp as $sma) $newma += $sma; // 将排序后的数组添加到输出数组
unset($ma, $sma, $temp); // 释放内存
return $newma;
}
}
?>
3
brettz9 throu gh yah
17 年前
通常,人们可能拥有一组数组,这些数组具有需要保持关联的并行数据(例如,一组元素的各种属性值可能存储在它们自己的数组中)。使用 array_multisort 本身,通过指定其他字段,可能会导致这种关联丢失,正如下面引用的文档示例中所述。

以文档中提供的此示例数据集为例
<?php
$ar1
= array("10", 100, 100, "a");
$ar2 = array(1, 3, "2", 1);
?>

该示例继续以这种方式对其进行排序
<?php
array_multisort
($ar1, $ar2);
?>

在这种情况下,虽然“10”在排序后仍然与第一个 '1' 相关联,但“2”和 '3' 的顺序与其原始顺序相反。

为了仅按一个字段排序(但仍然使其他数组相应排序),可以使用 array_keys(它将键数组化)来确保不执行任何进一步的子排序。这是有效的,因为 array_keys 正在创建没有重复项的数组(因为键是唯一的),因此后续字段对于子排序没有意义。

因此,使用以上数据,我们可以执行以下排序
<?php
$ar3
= array_keys($ar1);
array_multisort($ar1, $ar3, $ar2);
?>

当转储 $ar1 和 $ar2 时,它将给出

array(4) {
[0]=> string(2) "10"
[1]=> string(1) "a"
[2]=> int(100)
[3]=> int(100)
}
array(4) {
[0]=> int(1)
[1]=> int(1)
[2]=> int(3)
[3]=> string(1) "2"
}
2
m dot michalczyk at gmail dot com
15 年前
这是一个基于 za at byza dot it 的解决方案的实用示例,可以按任何维度对多维对象进行排序。
za at byza dot it
<?php
/* 示例结构 */
class person{
function
__construct($firstName, $lastName, $title, $position){
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->title = new title($title);
$this->position = new position($position);
}
}
class
title{
function
__construct($name){
$this->name = $name;
}

}
class
position{
function
__construct($name){
$this->name = $name;
}

}

$array[] = new person('Piotr', 'Sobiepanek', 'b', 'b');
$array[] = new person('Piotr', 'Kowalski', 'b', 'a');
$array[] = new person('Piotr', 'Michalski', 'a', 'a');
$array[] = new person('Jozef', 'Smietana', 'a', 'b');
$array[] = new person('Jozef', 'Cmietana', 'a', 'b');
$array[] = new person('Marcin', 'Kondraciuk', 'c', 'b');
$array[] = new person('Maksym', 'Kondraciuk', 'c', 'd');
$array[] = new person('Ambrozy', 'Kondraciuk', 'c', 'd');
$array[] = new person('Alojzy', 'Kondraciuk', 'c', 'd');

array_sort($array, 'title->name', 'position->name', 'lastName');
print_r($array);

/* 源代码 */

function hod(&$base, $path){
$keys = explode("->", $path);
$keys[0] = str_replace('$', '', $keys[0]);
$expression = '$ret = ';
$expression.= '$';
foreach (
$keys as $key){
if (++
$licz == 1){
$expression.= 'base->';
} else {
$expression.= $key.'->';
}
}
$expression = substr($expression, 0, -2);
$expression.= ';';
eval(
$expression);
return
$ret;
}

function
array_sort_func($a,$b=NULL) {
static
$keys;
if(
$b===NULL) return $keys=$a;
foreach(
$keys as $k) {
if(
$k[0]=='!') {
$k=substr($k,1);
if(
hod($a, '$a->'.$k)!==hod($b, '$b->'.$k)) {
return
strcmp(hod($b, '$b->'.$k),hod($a, '$a->'.$k));
}
}
else if(
hod($a, '$a->'.$k)!==hod($b, '$b->'.$k)) {
return
strcmp(hod($a, '$a->'.$k),hod($b, '$b->'.$k));
}
}
return
0;
}

function
array_sort(&$array) {
if(!
$array) return $keys;
$keys=func_get_args();
array_shift($keys);
array_sort_func($keys);
usort($array,"array_sort_func");
}
?>
3
Magento-用户
10 年前
当对一个(复杂)对象数组进行排序时,此函数可能会导致 “致命错误:嵌套层级过深”,因为它直接比较了后边数组中的元素,即使前面数组中的元素比较相等。 可以通过 Flag 参数来解决这个问题。
<?php
$sortKeys
= array_map($extractKey, $lotsOfComplexObjects);
array_multisort($sortKeys, $lotsOfComplexObjects, SORT_ASC, SORT_NUMERIC);
?>
我正在替换一个 'uasort()' 调用,因为它会导致大量的比较函数调用,而涉及的大多数对象都是递归的,因此速度显著降低。

如果这个“技巧”导致排序结果错误,你需要一个更好的键。
1
Patrick Adrichem
10 年前
如果你还没有安装 PHP 5.4 并且无法使用 SORT_NATURAL,这个函数可以对数组进行自然的多维排序,基于键值排序。

这个函数可以用于以下形式的数组:

array ( name => array( key => value ) )


array( name => value ).

不支持以下形式的数组: array( name => array( key => value), name => value)

<?php
static function natcasesortRecursive(&$aArray)
{
$bHasArrays = false;
foreach (
$aArray as $sKey => &$mValue)
{
if (
true === is_array($mValue))
{
self::natcasesortRecursive($mValue);
$bHasArrays = true;
}
}
if (
true === $bHasArrays)
{
uksort($aArray, 'strnatcasecmp');
}
else
{
natcasesort($aArray);
}
}
?>
1
jcharpentier at darkmira dot fr
10 年前
第二个例子缺乏精度。

示例 #2 对多维数组进行排序

解释是:
"在这个例子中,[...] 第二个将包含 1, 3, "2", 2, 1 (按照数字顺序排列,降序排列)。"
这可能会被误解,因为按照数字顺序降序排列的结果应该是 1, 1, "2", 2, 3.

我建议如下 (用最好的英语写会很棒 ^^):
"在这个例子中,[...] 第二个将包含 1, 3, "2", 2, 1 (排序方式与第一个相同,除了 3 和 "2" 按数字顺序排列,降序排列)。 因为它们对应于第一个数组中相同的条目 (100 和 100), 这些条目在第一次排序时无法排序."
1
alexander dot v at zend dot com
14 years ago
array_multisort 在 PHP 5.3 中正常工作,但它强制参数为引用。

对于常见的 `array_multisort()` 用法来说,这不会造成差异,但对于排序数量可变的数组,当涉及到 `call_user_func_array()` 函数时,会产生“问题”。

因此,所有要排序的数组都必须作为数组变量的引用收集到一个新数组中。

<?php
$sortArgs
= array();

for (...) {
...
$sortArgs[] = &$valuesArray;
...
}

call_user_func_array('array_multisort', $sortArgs);
?>

这(要求参数为引用)实际上并不是问题,因为否则源数组不会被排序。

重要提示!
如果在每次 `array_multisort()` 参数处理迭代中使用 `$valuesArray` 变量,请不要忘记销毁它。
如果不这样做,所有 `array_multisort()` 参数将包含相同的数组。

<?php
for (...) {
...
$sortArgs[] = &$valuesArray;
unset(
$valuesArray);
...
}
?>

最后一件重要的事情 :)
将排序数组收集到某个地方。否则,PHP 5.3 会将引用转换为值(当 `$valuesArray` 被销毁时),你将再次收到“Parameter 1 to array_multisort() expected to be a reference, value given”的警告。

最终代码应该如下所示

<?php
$sortArgs
= array();
$sortFieldValues = array();

for (...) {
...
$sortFieldValues[] = &$valuesArray;
$sortArgs[] = &$valuesArray;
unset(
$valuesArray);
...
}

call_user_func_array('array_multisort', $sortArgs);
?>
1
mech.cx
15 年前
我(和这里几乎所有人一样 :-) 想要根据关联子数组中的特定字段对二维数组进行排序。
我不喜欢文档示例中需要先遍历输入数组以创建子数组,然后在函数调用中使用这些子数组。

“php a-t-the-r-a-t-e chir.ag” (https://php.net/manual/en/function.array-multisort.php#60401) 写了一个非常巧妙的包装函数,我稍微重写了一下,更改了变量名并添加了注释(为了我的理智 :-) 主要原因)。
我发现了一个问题:输入数组作为最后一个参数传递给 `array_multisort`,但更改后的数组不是返回的数组。通过引用传递解决了这个问题。这似乎是由整个操作都在 `call_user_func_array` 内部引起的,如下所示。

<?php

$points
= array(1, 5, 2, 2);
$names = array('peter', 'mike', 'john Zoo', 'john Ab');

$source = array (
array (
'points' => 1, 'name' => 'Peter'),
array (
'points' => 5, 'name' => 'Mike'),
array (
'points' => 2, 'name' => 'John Zoo'),
array (
'points' => 2, 'name' => 'John Ab')
);

call_user_func_array('array_multisort', array($points, SORT_DESC, SORT_NUMERIC, $names, SORT_ASC, SORT_STRING, $source)); // 不起作用
print_r($source);
call_user_func_array('array_multisort', array($points, SORT_DESC, SORT_NUMERIC, $names, SORT_ASC, SORT_STRING, &$source)); // 起作用了!
print_r($source);

// 像这样调用:arrayColumnSort('points', SORT_DESC, SORT_NUMERIC, 'name', SORT_ASC, SORT_STRING, $source);

// 从 https://php.net/manual/en/function.array-multisort.php#60401 中稍微修改了一下

// arrayColumnSort(string $field, [options, ], string $field2, [options, ], .... , $array) /

//____________________
// arrayColumnSort() /
function arrayColumnSort() {
$args = func_get_args();
$array = array_pop($args);
if (!
is_array($array)) return false;
// 在这里,我们将从要排序的列中筛选出值,并将它们放入编号的“subar”(“子数组”)数组中。
// (因此,当按两个字段排序,每个字段都有两个修饰符(排序选项)时,这将创建 $subar0 和 $subar3)
foreach($array as $key => $row) // 遍历源数组
foreach($args as $akey => $val) // 遍历参数(字段和修饰符)
if(is_string($val)) // 如果参数是字段,则将它的值从源数组添加到子数组
${"subar$akey"}[$key] = $row[$val];
// $multisort_args 包含将进入 array_multisort() 的参数:子数组、修饰符和源数组
$multisort_args = array();
foreach(
$args as $key => $val)
$multisort_args[] = (is_string($val) ? ${"subar$key"} : $val);
$multisort_args[] = &$array; // 最后添加源数组,通过引用
call_user_func_array("array_multisort", $multisort_args);
return
$array;
}

?>
0
Anonymous
15 天前
PHP 中的数组是“有序映射”。“顺序”是内部的,与键的数值无关。
`Array_multisort()` 似乎是根据这种内部顺序进行排序的。它并没有维护数字键关联,然后根据这种关联重新编号。它维护内部顺序关联,数字键根据这种关联重新编号。字符串键至少在与数字键混合使用时,不会维护键关联或内部顺序关联。
换句话说,你的两个数组必须以类似的方式构建,否则可能会得到意外的结果。

<?php
$foo
=array("foo"=>"fazz", 7, 5,"sing"=>"soft", 9, 2, 0,"fing"=>"fong", 8, 1, 4);
$bar=array("bar"=>"bazz",17,45,"sing"=>"loud",29,72,90,"bing"=>"bong",38,81,54);
array_multisort($foo, $bar);
echo
var_dump($foo),"<br><br>",var_dump($bar),"<br><br>";
?>
array(11) { [0]=> int(0) [1]=> int(1) [2]=> int(2) [3]=> int(4) [4]=> int(5) [5]=> int(7) [6]=> int(8) [7]=> int(9) ["foo"]=> string(4) "fazz" ["fing"]=> string(4) "fong" ["sing"]=> string(4) "soft" }

array(11) { [0]=> int(90) [1]=> int(81) [2]=> int(72) [3]=> int(54) [4]=> int(45) [5]=> int(17) [6]=> int(38) [7]=> int(29) ["bar"]=> string(4) "bazz" ["bing"]=> string(4) "bong" ["sing"]=> string(4) "loud" }

<?php
$foo
=array("foo"=>"fazz", 7, 5,"sing"=>"soft", 9, 2, 0,"fing"=>"fong", 8, 1, 4);
$bar=array(17,45,29,72,90,"sing"=>"loud",38,81,54,"bing"=>"bong","bar"=>"bazz");
array_multisort($foo, $bar);
echo
var_dump($foo),"<br><br>",var_dump($bar),"<br><br>";
?>
array(11) { [0]=> int(0) [1]=> int(1) [2]=> int(2) [3]=> int(4) [4]=> int(5) [5]=> int(7) [6]=> int(8) [7]=> int(9) ["foo"]=> string(4) "fazz" ["fing"]=> string(4) "fong" ["sing"]=> string(4) "soft" }

array(11) { [0]=> int(38) ["bar"]=> string(4) "bazz" ["sing"]=> string(4) "loud" ["bing"]=> string(4) "bong" [1]=> int(29) [2]=> int(45) [3]=> int(54) [4]=> int(90) [5]=> int(17) [6]=> int(81) [7]=> int(72) }

我的项目中的数组使用 <?php $foo[]=$filename ?> 语法在循环中构建,并在循环中随机位置添加一个字符串键属性来存储找到的目录名,同时构建一个包含完整文件路径的匹配数组,但不包含目录信息。即使在事后向文件路径数组添加一个“伪造”的匹配字符串键属性后,也不能使用 Array_multisort 对两个数组都按文件名排序。
我不得不将文件路径数组构建在一个单独的变量中,进行排序,然后在事后将其作为字符串键属性添加到文件名数组中。
0
Sbastien
1 年前
对于多维或自定义排序,shuttle 操作符可以作为 array_multisort() 的一个智能替代方案。

<?php

$data
= [
[
'name' => 'John Smith', 'status' => 'Offline'],
[
'name' => 'Anne Onyme', 'status' => 'Online'],
[
'name' => 'Alan Smithee', 'status' => 'Online'],
];

// 首先是 Online,然后按字母顺序排列名称
usort($data, fn ($a, $b) => [
[
'Online' => 1, 'Offline' => 2][$a['status']],
$a['name'],
] <=> [
[
'Online' => 1, 'Offline' => 2][$b['status']],
$b['name'],
]);

print_r($data);

/*
Array
[0] => Array
[name] => Alan Smithee
[status] => Online
[1] => Array
[name] => Anne Onyme
[status] => Online
[2] => Array
[name] => John Smith
[status] => Offline
*/
0
498936940 at qq dot com
2 年前
根据多个键任意排序二维数组

```
array_multisort (
array_column($array, 'key1'), SORT_ASC,
array_column($array, 'key2'), SORT_DESC,
array_column($array, 'key3'), SORT_ASC,
array_column($array, 'key4'), SORT_DESC,
$array
);
```
0
Hayley Watson
6 年前
array_multisort() 的精简包装,以便在对关联数组数组进行排序时,可以按其名称指定要排序的列,而不必将它们作为显式数组提取出来。请注意,您也可以对数字索引列进行排序,前提是您将索引强制转换为字符串(否则它们将与 SORT_* 常量混淆)。

<?php
function array_multisort_by_column(&$array, ...$spec)
{
return
array_multisort($array, ...array_map(function($s)use($array)
{
return
is_string($s) ? array_column($array, $s) : $s;
},
$spec));
}
?>
1
scott - evolove - net - work it out
18 years ago
对关联数组数组进行排序的一种非常简单的方法是使用 usort。

我需要按其“distance”值对 20 个数据结构数组进行排序

数组
(
[0] => 数组
(
[blahblah] => blahblah
[distance] => 6
)

[1] => 数组
(
你明白了......

以下是代码

--------------------
usort($results, "distributor_compare");

/**
* usort 回调函数
*/
function distributor_compare($a, $b) {
$adist = intval($a['distance']);
$bdist = intval($b['distance']);

if ($adist == $bdist) {
return 0;
}
return ($adist < $bdist) ? -1 : 1;
}
--------------------
0
ArkieGuy
6 年前
<?php

/**
* array_multisort 包装函数 - 按键数组排序数据数组
*
* $data : 要排序的多维数组
* $keys : 包含“键”字段名称和可选顺序/标志的数组
*
* 示例:$keys[2] = [ 'Animal', SORT_DESC, SORT_REGULAR | SORT_FLAG_CASE ];
* $keys[1] = [ 'Name' ];
*
* 语法:if( multiSort( $data, $keys ) ) print_r( $data );
*
* 成功返回 TRUE,失败返回 FALSE。
*/
function multiSort( &$data, $keys ) {

// 排序键 - 允许按任意顺序传递键数组
ksort( $keys );

// 遍历键数组构建参数传递给 call_user_function
// (必须索引为 0-n,其中 n 是要排序的数据)
foreach( $keys as $key ) {
// 遍历键参数列表
foreach( $key as $element => $value )
if(
$element == 0 )
// 添加包含名为 $data 列的列值的数组
$args[] = array_column( $data, $value );
else
// 添加传递的用于排序顺序/标志的整数
// 注意:如果您尝试将字符串值(例如来自 INI)发送给
// array_multisort 用于 sort_order 或 sort_flags,您将收到
// “参数 #x 应为数组或排序标志”。
// 强制转换为 int 可解决此问题
$args[] = (int)$value;
}

// 将要排序的数组添加到参数列表中
$args[] = &$data;

// 调用 array_multisort 按键顺序排序数组
return( call_user_func_array( 'array_multisort', $args ) );
}

/* 示例 */

echo "<PRE>";

// 数据数组(可以是关联数组,也可以使用列号)
$data = [
[
'Name' => 'Brown', 'Animal' => 'Dog'],
[
'Name' => 'Smith', 'Animal' => 'Cat'],
[
'Name' => 'Jones', 'Animal' => 'Dog'],
[
'Name' => 'Jones', 'Animal' => 'Pig'],
[
'Name' => 'Bennett', 'Animal' => 'Cat'],
[
'Name' => 'Astor', 'Animal' => 'Cat'],
[
'Name' => 'Jones', 'Animal' => 'Cat'],
];

// 包含“键”的数组 - 每个键都是列的名称,
// 以及可选的排序顺序和/或排序标志
// 将按 Name 然后 Animal 排序,因为键数组在使用之前是按键排序的
$keys[2] = [ 'Animal', SORT_DESC, SORT_REGULAR | SORT_FLAG_CASE ];
$keys[1] = [ 'Name' ];

// 调用包装函数
if( ! multiSort( $data, $keys ) )
die(
'Sort Failed' );

print_r( $data );
?>
0
walterquez at gmail dot com
6 年前
要排序简单的多维数组,请使用数组本身作为修饰符。这将根据第一列进行排序。无需编写自定义函数。

$data = array(
array('volume' => 67, 'edition' => 2),
array('volume' => 86, 'edition' => 1),
array('volume' => 85, 'edition' => 6),
array('volume' => 98, 'edition' => 2),
array('volume' => 86, 'edition' => 6),
array('volume' => 67, 'edition' => 7)
)

array_multisort($data, $data);
-2
qasastechnology at gmail dot com
5 年前
不区分大小写的排序
要执行不区分大小写的排序

$array = [
[
'name' => 'b',
'label' => 'ball'
],
[
'name' => 'a',
'label' => 'apple'
],
[
'name' => 'l',
'label' => 'Lighting'
],
[
'name' => 'w',
'label' => 'With'
]

];

public function sortArray($array) {

if (count($array)) {
array_multisort(array_map(function($element) {
return strtolower($element['label']);
}, $array), SORT_ASC, $array);
}

返回 $array;
}
0
matt at wennersten dot org
9 年前
许多用户为泛化 array_multisort 做出了贡献,贡献了一些巧妙的包装函数。但是,我们中的一些人可能只需要一个简单的示例来说明如何对任意多维数组(例如数据库结果集)进行排序,例如对命名字段进行排序。

考虑一个存储在文件系统上的语音录制(Clip 对象)数组,并通过数据库表进行引用

$fetchClipQuery = "SELECT * from voiceclips";
if ( !$result = $this->db->query($fetchClipQuery) ) {
$errormessage = $this->db->errno;
$errormessage .= $this->db->error;
} else {
while($row = $result->fetch_assoc()){
$clip = new Clip();
$clip->populate($row['clipURL']);
$clips[] = array("speaker"=>$row['speaker'],"duration"=>$row['duration'],"clip"=>$clip);
}

// 我们现在有一个名为 clips[] 的数组,看起来像这样

array("speaker"=>"Obama","duration"=>"22:00","clip"=>...<some arbitrary object>...);

// 假设我们要按演讲者对数组进行排序
$sortkeyname = "speaker";
// 执行排序
$sortkeyarray = array();
foreach ($clips as $key => $row){
$sortkeyarray[$key] = $row[$sortkeyname];
}
array_multisort($sortkeyarray, SORT_DESC, $clips);

// 假设我们要按持续时间对数组进行排序
$sortkeyname = "duration";
// 执行排序
$sortkeyarray = array();
foreach ($clips as $key => $row){
$sortkeyarray[$key] = $row[$sortkeyname];
}
array_multisort($sortkeyarray, SORT_DESC, $clips);

...等等。
0
plugboard at web dot de
11 年前
对对象数组进行排序

示例对象 [$object 包含对象数组]:(类:test)
----------------------------------

test 对象 (
[Artikel] => Array (
[0] => test 对象 (
[id] => 1
[title] => CCCC
)
[1] => test 对象 (
[id] => 2
[title] => AAAA
)
[2] => test 对象 (
[id] => 3
[title] => DDDD
)
[3] => test 对象 (
[id] => 4
[title] => BBBB
)
)
)

----------------------------------

简单的 PHP 函数:sort_arr_of_obj()

<?php
// --------------------------------------

/*
* -------- 函数参数 --------
* $array ........ 对象数组
* $sortby ....... 要排序的对象键
* $direction ... 'asc' = 升序
* --------
*/

function sort_arr_of_obj($array, $sortby, $direction='asc') {

$sortedArr = array();
$tmp_Array = array();

foreach(
$array as $k => $v) {
$tmp_Array[] = strtolower($v->$sortby);
}

if(
$direction=='asc'){
asort($tmp_Array);
}else{
arsort($tmp_Array);
}

foreach(
$tmp_Array as $k=>$tmp){
$sortedArr[] = $array[$k];
}

return
$sortedArr;

}


// --------------------------------------
?>

示例调用
----------------------------------

<?php

$sorted
->Artikel = sort_arr_of_obj($object->Artikel,'title','asc');

?>

示例结果:$sorted (类:test)
----------------------------------

test 对象 (
[Artikel] => Array (
[0] => test 对象 (
[id] => 2
[title] => AAAA
)
[1] => test 对象 (
[id] => 4
[title] => BBBB
)
[2] => test 对象 (
[id] => 1
[title] => CCCC
)
[3] => test 对象 (
[id] => 3
[title] => DDDD
)

)
)

-------------------------

:)
0
info at ichier dot de
13 年前
如果您想按列对数组进行排序,那么这个函数就可以满足您的需求。

<?php
function array_csort() { // 由 Ichier2003 编写
$args = func_get_args();
$marray = array_shift($args);
$msortline = 'return(array_multisort(';
foreach (
$args as $arg) {
$i++;
if (
is_string($arg)) {
foreach (
$marray as $row) {
$sortarr[$i][] = $row[$arg];
}
} else {
$sortarr[$i] = $arg;
}
$msortline .= '$sortarr['.$i.'],';
}
$msortline .= '$marray));';
eval(
$msortline);
return
$marray;
}
?>
0
thierryzo at hotmail dot fr
13 年前
// 对这种结构的数组进行排序的一种非常简单的方法。

<?php
$myArray
=array(
array(
"NUMCIE" => "001","REF" => "RXL","COLOR" => "RED","L1" => 4),
array(
"NUMCIE" => "001","REF" => "RXL","COLOR" => "BLUE","L1" => 6),
array(
"NUMCIE" => "001","REF" => "RHQ","COLOR" => "RED","L1" => 4),
array(
"NUMCIE" => "002","REF" => "RXL","COLOR" => "YELLOW","L1" => 8));


foreach(
$myArray as $c=>$key) {
$sort_numcie[] = $key['NUMCIE'];
$sort_ref[] = $key['REF'];
$sort_color[] = $key['COLOR'];
}

array_multisort($sort_numcie, SORT_ASC, $sort_ref, SORT_STRING, $myArray);
print_r($myArray);

?>

// 结果数组

数组
(
[0] => 数组
(
[NUMCIE] => 001
[REF] => RHQ
[COLOR] => RED
[L1] => 4
)

[1] => 数组
(
[NUMCIE] => 001
[REF] => RXL
[COLOR] => BLUE
[L1] => 6
)

[2] => Array
(
[NUMCIE] => 001
[REF] => RXL
[COLOR] => RED
[L1] => 4
)

[3] => Array
(
[NUMCIE] => 002
[REF] => RXL
[COLOR] => YELLOW
[L1] => 8
)

)
0
Jaak Tamre
13 年前
我遇到了对 SimpleXMLElement 列表进行排序的问题。我找到了一个简洁的解决方案。

我有一个包含票证对象的数组:$ticketList = $xml->Tickets;

<?php
// 按 ValidOnDate 排序
$tickets = array();
$valid = array();
foreach (
$ticketList as $row) {
$tickets[] = $row;
$valid[] = DateHandler::parseDate($row->ValidOnDate);
}
array_multisort($valid, SORT_DESC, $tickets);
?>

只需创建一个包含要排序的对象项的数组,以及一个包含相同对象的新数组,该数组将根据第一个数组的顺序进行重新排序。

PS:我自己的 parseDate(date) 函数针对不同的日期格式返回 Unix 时间戳。
0
Zbigniew Heintze http://bigweb.pl
15 年前
<?php
/**
* 对 DB 结果进行排序
*
* @param array $data 作为关联数组的 sql 查询结果
*
* 其余参数可选
* [, string $name [, mixed $name 或 $order [, mixed $name 或 $mode]]]
* $name string - 数据库表中的列名
* $order integer - 排序方向,升序(SORT_ASC)或降序(SORT_DESC)
* $mode integer - 排序模式(SORT_REGULAR、SORT_STRING、SORT_NUMERIC)
*
* <code>
* <?php
* // 可以按多个列对数据进行排序,例如:
* $data = array();
* for ($i = 1; $i <= 10; $i++) {
* $data[] = array( 'id' => $i,
* 'first_name' => sprintf('first_name_%s', rand(1, 9)),
* 'last_name' => sprintf('last_name_%s', rand(1, 9)),
* 'date' => date('Y-m-d', rand(0, time()))
* );
* }
* $data = sortDbResult($data, 'date', SORT_DESC, SORT_NUMERIC, 'id');
* printf('<pre>%s</pre>', print_r($data, true));
* $data = sortDbResult($data, 'last_name', SORT_ASC, SORT_STRING, 'first_name', SORT_ASC, SORT_STRING);
* printf('<pre>%s</pre>', print_r($data, true));
* ?>
* </code>
*
* @return array $data - 已排序的数据
*/
function sortDbResult(array $data /*$name, $order, $mode*/) {
$_argList = func_get_args();
$_data = array_shift($_argList);
if (empty(
$_data)) {
return
$_data;
}
$_max = count($_argList);
$_params = array();
$_cols = array();
$_rules = array();
for (
$_i = 0; $_i < $_max; $_i += 3)
{
$_name = (string) $_argList[$_i];
if (!
in_array($_name, array_keys(current($_data)))) {
continue;
}
if (!isset(
$_argList[($_i + 1)]) || is_string($_argList[($_i + 1)])) {
$_order = SORT_ASC;
$_mode = SORT_REGULAR;
$_i -= 2;
} else if (
3 > $_argList[($_i + 1)]) {
$_order = SORT_ASC;
$_mode = $_argList[($_i + 1)];
$_i--;
} else {
$_order = $_argList[($_i + 1)] == SORT_ASC ? SORT_ASC : SORT_DESC;
if (!isset(
$_argList[($_i + 2)]) || is_string($_argList[($_i + 2)])) {
$_mode = SORT_REGULAR;
$_i--;
} else {
$_mode = $_argList[($_i + 2)];
}
}
$_mode = $_mode != SORT_NUMERIC
? $_argList[($_i + 2)] != SORT_STRING ? SORT_REGULAR : SORT_STRING
: SORT_NUMERIC;
$_rules[] = array('name' => $_name, 'order' => $_order, 'mode' => $_mode);
}
foreach (
$_data as $_k => $_row) {
foreach (
$_rules as $_rule) {
if (!isset(
$_cols[$_rule['name']])) {
$_cols[$_rule['name']] = array();
$_params[] = &$_cols[$_rule['name']];
$_params[] = $_rule['order'];
$_params[] = $_rule['mode'];
}
$_cols[$_rule['name']][$_k] = $_row[$_rule['name']];
}
}
$_params[] = &$_data;
call_user_func_array('array_multisort', $_params);
return
$_data;
}
?>
0
matt at idizinc dot com
15 年前
我在一些论坛上寻找解决这个问题的答案,但没有找到,所以我想出一个可能在某些情况下有用的解决方案。

如何根据数组中的一个字段对数组进行排序,并在数字相等时随机解决?

代码
<?php

foreach($list as $temp_list)
{
$sort_aux[] = ($temp_list['column_to_sort_by']+(rand(1, 9)/10));
}
array_multisort($sort_aux, SORT_NUMERIC, $list);

?>

示例

$list[]=array('name'=>'Tom', 'score'=>3);
$list[]=array('name'=>'Sam', 'score'=>3);
$list[]=array('name'=>'Joey', 'score'=>1);

说明
我借鉴了上面找到的一个例子,它展示了如何根据数组中的一个列/字段对数组进行排序。
我添加了 "+(rand(1,9)/10)" 以随机地将 0.1 到 0.9 加到他们的分数上,以解决平局。(显然,这个特定示例仅在您按整数排序时才有效,因此您可能需要修改它以适应您的需求。)

希望这对某人有所帮助。
0
isp dot php at spspft dot de
15 年前
我想报告与消息相关的困惑

Warning: Call-time pass-by-reference has been deprecated; If you would like to pass it by reference, modify the declaration of array_multisort(). If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file...

来自类似这样的行

array_multisort (&$keyarr, &$arr );// sort against this keys

此消息不能通过更改错误报告级别轻松关闭,因为它是在解析时生成的 - 而不是执行时。

我认为此消息具有误导性,因为无论如何,参数都是通过引用传递到 array_multisort 中的。

遇到此消息的任何人都应该知道无需执行任何操作,只需删除与符号 (&) 即可。
我被此消息欺骗了,因为我当然希望获得*排序后的*数组。并且找不到 ini 文件或 array_multisort 的声明。
我认为在 array_multisort 的此描述中,应该在定义中列出按引用调用。

希望这对某人有所帮助
0
seiffs_at_centrum-dot-cz
15 年前
对 php_multisort($data,$keys) 需要进行两个更正

// 排序表达式
$i=0;
$sort=''; // 这里
foreach ($keys as $k){
if($i>0){$sort.=',';}
$sort.='$cols[\''.$k['key'].'\']'; // 以及这里
if($k['sort']){$sort.=',SORT_'.strtoupper($k['sort']);}
if($k['type']){$sort.=',SORT_'.strtoupper($k['type']);}
$i++;
}
0
Jon L. -- intel352 [AT] gmail [DOT] com
17 年前
这是我使用 POST 值进行动态多排序的解决方案。这并没有考虑需要一次按多列排序的需求,但可以为此目的进行修改。

<?php
/**
* @desc 您真的应该根据有效可能性列表验证发布的排序方向。
* 选项是 SORT_ASC、SORT_DESC 等,如 array_multisort 文档中所示
*/
$sort['direction'] = $_POST['sort_direction'] ? $_POST['sort_direction'] : 'SORT_ASC';
$sort['field'] = $_POST['sort_field'] ? $_POST['sort_field'] : 'value';

$array_to_sort = array();
$array_to_sort['TestCase1'] = array('name'=>'Test1','value'=>'218');
$array_to_sort['TestCase2'] = array('name'=>'Test2','value'=>'10');
$array_to_sort['TestCase3'] = array('name'=>'Test3','value'=>'64');

/**
* @desc 使用值构建列,以便在 php 中进行排序
*/
$sort_arr = array();
foreach(
$array_to_sort AS $uniqid => $row){
foreach(
$row AS $key=>$value){
$sort_arr[$key][$uniqid] = $value;
}
}

print
'<b>排序前</b>: <br> <pre>';
print_r($array_to_sort);
print
'</pre>';

if(
$sort['direction']){
array_multisort($sort_arr[$sort['field']], constant($sort['direction']), $array_to_sort);
}

print
'<b>排序后</b>: <br> <pre>';
print_r($array_to_sort);
print
'</pre>';

?>

此示例输出

排序前

数组
(
[TestCase1] => Array
(
[name] => Test1
[value] => 218
)

[TestCase2] => Array
(
[name] => Test2
[value] => 10
)

[TestCase3] => Array
(
[name] => Test3
[value] => 64
)

)

排序后

数组
(
[TestCase2] => Array
(
[name] => Test2
[value] => 10
)

[TestCase3] => Array
(
[name] => Test3
[value] => 64
)

[TestCase1] => Array
(
[name] => Test1
[value] => 218
)

)
0
KES http://kes.net.ua
18 years ago
<?
// 按第二列排序,然后按第一列排序
$orderBy=array('0'=>'desc', 'first'=>'asc');

function KES_cmp($a, $b) {
global $orderBy;
$result= 0;
foreach( $orderBy as $key => $value ) {
if( $a[$key] == $b[$key] ) continue;
$result= ($a[$key] < $b[$key])? -1 : 1;
if( $value=='desc' ) $result= -$result;
break;
}
return $result;
}

$result= array();
$result[]= array( 'first'=>6, 2);
$result[]= array( 'first'=>3, 2);
$result[]= array( 'first'=>1, 3);
$result[]= array( 'first'=>1, 2);
$result[]= array( 'first'=>6, 1);

print "<b>源代码</b>";
print_r($result);

usort($result, 'KES_cmp');
print "<b>结果</b>";
print_r($result);
?>
0
php a-t-the-r-a-t-e chir.ag
18 years ago
Re: phu at kungphu, 19-Dec-2005 11:36

asort($test) 不允许我指定要按哪些列进行 ASC/DESC、NUMERIC/STRING 等排序。

我的数据与您指定的数据类似。现在我想按 points DESC 和 name ASC 对 $test 进行排序。这是我基于此页面上的建议而编写的函数。它使用 array_multisort(因此就像它一样起作用:保留字符串键等)。

<?php

function arrayColumnSort()
{
$n = func_num_args();
$ar = func_get_arg($n-1);
if(!
is_array($ar))
return
false;

for(
$i = 0; $i < $n-1; $i++)
$col[$i] = func_get_arg($i);

foreach(
$ar as $key => $val)
foreach(
$col as $kkey => $vval)
if(
is_string($vval))
${
"subar$kkey"}[$key] = $val[$vval];

$arv = array();
foreach(
$col as $key => $val)
$arv[] = (is_string($val) ? ${"subar$key"} : $val);
$arv[] = $ar;

call_user_func_array("array_multisort", $arv);
return
$ar;
}

$test["pete"]['points']=1;
$test["pete"]['name']='Peter';

$test["mike"]['points']=5;
$test["mike"]['name']='Mike';

$test["zoo"]['points']=2;
$test["zoo"]['name']='John Zoo';

$test["ab"]['points']=2;
$test["ab"]['name']='John Ab';

$test1 = $test;

asort($test1);

$test2 = arrayColumnSort("points", SORT_DESC, SORT_NUMERIC, "name", SORT_ASC, SORT_STRING, $test);

print_r($test1); // asort
print_r($test2); // arrayColumnSort

?>

asort 函数输出

数组
(
[pete] => Array
(
[points] => 1
[name] => Peter
)

[ab] => Array
(
[points] => 2
[name] => John Ab
)

[zoo] => Array
(
[points] => 2
[name] => John Zoo
)

[mike] => Array
(
[points] => 5
[name] => Mike
)

)

arrayColumnSort 函数输出

数组
(
[mike] => Array
(
[points] => 5
[name] => Mike
)

[ab] => Array
(
[points] => 2
[name] => John Ab
)

[zoo] => Array
(
[points] => 2
[name] => John Zoo
)

[pete] => Array
(
[points] => 1
[name] => Peter
)

)
0
joao at intrasystems dot com dot br
19 年前
多维数组按某个字段排序的示例

$result[0]['nome']='Joao';
$result[0]['order']=5;
$result[1]['nome']='Pedro';
$result[1]['order']=1;
$result[2]['nome']='Marcelo';
$result[2]['order']=3;

foreach($result as $res)
$sortAux[] = $res['order'];

array_multisort($sortAux, SORT_ASC, $result);

print_r($result);

输出结果

数组
(
[0] => 数组
(
[nome] => Pedro
[order] => 1
)

[1] => 数组
(
[nome] => Marcelo
[order] => 3
)

[2] => Array
(
[nome] => Joao
[order] => 5
)

)
0
meddle at dzygn.com
19 年前
如果你想根据键名对多维数组进行排序,则不能使用 array_multisort。 例如:对于名为 $archivos 的数组,其打印方式如下

数组
(
[0] => 数组
(
[index] => 0
[name] => test
)

[1] => 数组
(
[index] => 0
[name] => watertaxi.jpg
)

[2] => Array
(
[index] => 0
[name] => 2_0003.JPG
)

[3] => Array
(
[index] => 0
[name] => 24A_0025.JPG
)

[4] => Array
(
[index] => 1
[name] => _CIMG3501.JPG
)

)

如果我想按“name”排序,我会使用

function comparar($a, $b) {
return strnatcasecmp($a["name"], $b["name"]);
}
usort($archivos, "comparar");

此函数使用“自然顺序”算法 (strnatcasecmp) 执行不区分大小写的字符串比较,结果为

数组
(
[0] => 数组
(
[index] => 0
[name] => 2_0003.JPG
)

[1] => 数组
(
[index] => 0
[name] => 24A_0025.JPG
)

[2] => Array
(
[index] => 0
[name] => test
)

[3] => Array
(
[index] => 0
[name] => watertaxi.jpg
)

[4] => Array
(
[index] => 1
[name] => _CIMG3501.JPG
)

)
-1
rnacken at gmail dot com
12 年前
当我在开发一个搜索引擎时,需要根据多个参数对结果进行排序,我在使用 multisort 擦除 (数字) 索引的问题上卡住了。 有时,保持这些索引完整非常重要。 在我的情况下,索引是 ID,值是考虑到之前的查询,对象的相关性百分比。
例如:$searchResult = (23 => 0.3,
102 => 0.5,
11 => 0.5,
340 => 0.5,
10 => 0.9);

我想使用 array_multisort 先按 ID 降序排序,然后按值降序排序。 也就是说,我想先显示最高的数值,但如果两个 (或更多) 对象的值相同,则先显示较高的 ID。
例如:$searchResult = (10 => 0.9,
340 => 0.5,
102 => 0.5,
11 => 0.5,
23 => 0.3);

我认为最简单的方法是
<?php
// 创建一个包含 $searchResult 值和键的 2 层数组
$array = array(
$searchResult,
array_keys($searchResult)
);
// 使用 multisort,先对值进行排序,然后对键进行排序。 这将擦除 $searchResult 数组中的索引
array_multisort($array[0], SORT_DESC, $array[1], SORT_DESC);
// 将排序后的键返回到 $searchResult 数组中
$searchResult = array_combine($array[1], $array[0]);
unset(
$array); // 清理一些内存
?>
-2
dwalter at seznam dot cz
4 年前
我用我的语言对多维关联数组的解决方案,它尊重字母表中的所有字符
<?php
setlocale
(LC_COLLATE, 'cs_CZ.utf-8');
$prijmeni_zamestnancu = array_column($DBzamestnanci, 'prijmeni');
array_multisort($prijmeni_zamestnancu, SORT_ASC, SORT_LOCALE_STRING, $DBzamestnanci);
?>
To Top