如何按值对多维数组进行排序

如何根据“order”键的值对该数组进行排序?

尽管这些值当前是顺序的,但它们并不总是顺序的。

Array([0] => Array([hashtag] => a7e87329b5eab8578f4f1098a152d6f4[title] => Flower[order] => 3)
[1] => Array([hashtag] => b24ce0cd392a5b0b8dedc66c25213594[title] => Free[order] => 2)
[2] => Array([hashtag] => e7d31fc0602fb2ede144d18cdffd816b[title] => Ready[order] => 1))
1071558 次浏览
function aasort (&$array, $key) {$sorter = array();$ret = array();reset($array);foreach ($array as $ii => $va) {$sorter[$ii] = $va[$key];}asort($sorter);foreach ($sorter as $ii => $va) {$ret[$ii] = $array[$ii];}$array = $ret;}
aasort($your_array, "order");

我使用这个功能:

function array_sort_by_column(&$arr, $col, $dir = SORT_ASC) {$sort_col = array();foreach ($arr as $key => $row) {$sort_col[$key] = $row[$col];}
array_multisort($sort_col, $dir, $arr);}
array_sort_by_column($array, 'order');

编辑这个答案至少有十年的历史了,现在可能有更好的解决方案,但我在一些评论中添加了一些额外的信息。

它之所以有效,是因为array_multisort()可以对多个数组进行排序。示例输入:

Array([0] => Array([hashtag] => a7e87329b5eab8578f4f1098a152d6f4[title] => Flower[order] => 3)
[1] => Array([hashtag] => b24ce0cd392a5b0b8dedc66c25213594[title] => Free[order] => 2)

首先创建$sort_col,它是一个二维数组,值是我们想要排序的值,键与输入数组匹配。例如,对于这个输入,选择key$sort_col"order"我们得到:

Array([0] => 3,[1] => 2)

array_multisort()然后对该数组进行排序(导致键顺序1, 0),但这只是二维数组。因此,原始输入数组也作为$rest参数传递。由于键匹配,它将被排序,因此其键也以相同的顺序,给出所需的结果。

备注:

  • 它通过引用传递,以便在适当的位置修改提供的数组。
  • array_multisort()可以像这样对多个附加数组进行排序,而不仅仅是一个

我通常使用usort,并传递我自己的比较函数。在这种情况下,它很简单:

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

在PHP 7中使用宇宙飞船运算符:

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

尝试usort。如果您仍在使用PHP 5.2或更早版本,则必须首先定义一个排序函数:

function sortByOrder($a, $b) {return $a['order'] - $b['order'];}
usort($myArray, 'sortByOrder');

从PHP 5.3开始,您可以使用匿名函数:

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

使用PHP 7,您可以使用宇宙飞船操作员

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

最后,在PHP 7.4中,您可以使用箭头函数清理一下:

usort($myArray, fn($a, $b) => $a['order'] <=> $b['order']);

要将其扩展到多维排序,请引用第二/第三个排序元素,如果第一个为零-最好在下面解释。您也可以使用它对子元素进行排序。

usort($myArray, function($a, $b) {$retval = $a['order'] <=> $b['order'];if ($retval == 0) {$retval = $a['suborder'] <=> $b['suborder'];if ($retval == 0) {$retval = $a['details']['subsuborder'] <=> $b['details']['subsuborder'];}}return $retval;});

如果您需要保留键关联,请使用uasort()-请参阅手册中的数组排序函数的比较

$sort = array();$array_lowercase = array_map('strtolower', $array_to_be_sorted);array_multisort($array_lowercase, SORT_ASC, SORT_STRING, $alphabetically_ordered_array);

这需要照顾大写和小写字母。

要按“title”键的值对数组进行排序,请使用:

uasort($myArray, function($a, $b) {return strcmp($a['title'], $b['title']);});

strcmp比较字符串。

uasort()维护定义的数组键。

让我们面对现实:PHP没有确实有一个简单的开箱即用的函数来正确处理每个数组排序场景。

这个例程很直观,这意味着更快的调试和维护:

// Automatic population of the array$tempArray = array();$annotations = array();// ... some code// SQL $sql retrieves result array $result// $row[0] is the ID, but is populated out of order (comes from// multiple selects populating various dimensions for the same DATE// for examplewhile($row = mysql_fetch_array($result)) {$needle = $row[0];arrayIndexes($needle);  // Create a parallel array with IDs only$annotations[$needle]['someDimension'] = $row[1]; // Whatever}asort($tempArray);foreach ($tempArray as $arrayKey) {$dataInOrder = $annotations[$arrayKey]['someDimension'];// .... more code}
function arrayIndexes ($needle) {global $tempArray;if (!in_array($needle, $tempArray)) {array_push($tempArray, $needle);}}

为此,我们可以使用“array_multisort”方法对多个或多维数组进行排序。它的方法参数是

  • $key-正在排序的数组
  • SORT_ASC-排序顺序(升序)
  • 排序标志(正常比较项目(不更改类型)或数字或字符串)
  • $new-然后是数组的其余部分。只有元素对应于前一个
    中的等效元素数组进行比较。

默认情况下,“排序标志”SORT_REGULAR,并被省略。

$new = [['hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4','title' => 'Flower','order' => 3,],['hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594','title' => 'Free','order' => 2,],['hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b','title' => 'Ready','order' => 1,],];$keys = array_column($new, 'order');array_multisort($keys, SORT_ASC, $new);var_dump($new);

结果:

Array([0] => Array([hashtag] => e7d31fc0602fb2ede144d18cdffd816b[title] => Ready[order] => 1)[1] => Array([hashtag] => b24ce0cd392a5b0b8dedc66c25213594[title] => Free[order] => 2)[2] => Array([hashtag] => a7e87329b5eab8578f4f1098a152d6f4[title] => Flower[order] => 3))

最灵活的方法是使用这种方法:

Arr::sortByKeys(array $array, $keys, bool $assoc = true): array

原因如下:

  • 您可以按任何键排序(也像'key1.key2.key3'['k1', 'k2', 'k3']一样嵌套)

  • 它适用于关联数组和非关联数组($assoc标志)

  • 它不使用引用-它返回一个新的排序数组

在你的情况下,它会像这样简单:

$sortedArray = Arr::sortByKeys($array, 'order');

此方法是这个图书馆的一部分。

使用array_multisort()array_map()

array_multisort(array_map(function($element) {return $element['order'];}, $array), SORT_ASC, $array);
print_r($array);

演示

如果有人需要根据一个键排序,最好是使用下面的:

usort($array, build_sorter('order'));
function build_sorter($key) {return function ($a, $b) use ($key) {return strnatcmp($a[$key], $b[$key]);};}

此解决方案适用于usort(),具有易于记忆的多维排序符号。使用太空船运算符<=>,可从PHP 7获得。

usort($in,function($a,$b){return $a['first']   <=> $b['first']  //first asc?: $a['second']  <=> $b['second'] //second asc?: $b['third']   <=> $a['third']  //third desc (a b swapped!)//etc;});

示例:

$in = [['firstname' => 'Anton', 'surname' => 'Gruber', 'birthdate' => '03.08.1967', 'rank' => 3],['firstname' => 'Anna', 'surname' => 'Egger', 'birthdate' => '04.01.1960', 'rank' => 1],['firstname' => 'Paul', 'surname' => 'Mueller', 'birthdate' => '15.10.1971', 'rank' => 2],['firstname' => 'Marie', 'surname' => 'Schmidt ', 'birthdate' => '24.12.1963', 'rank' => 2],['firstname' => 'Emma', 'surname' => 'Mueller', 'birthdate' => '23.11.1969', 'rank' => 2],];

第一个任务:按排名asc排序,姓asc

usort($in,function($a,$b){return $a['rank']      <=> $b['rank']     //first asc?: $a['surname']   <=> $b['surname']  //second asc;});

第二个任务:按排名desc,姓asc,第一名asc排序

usort($in,function($a,$b){return $b['rank']      <=> $a['rank']       //first desc?: $a['surname']   <=> $b['surname']    //second asc?: $a['firstname'] <=> $b['firstname']  //third asc;});

第三个任务:按等级排序desc,出生日期asc

日期不能按此符号排序。它是用strtotime转换的。

usort($in,function($a,$b){return $b['rank']      <=> $a['rank']       //first desc?: strtotime($a['birthdate']) <=> strtotime($b['birthdate'])    //second asc;});

您可以使用usort和带有回调函数的用户定义排序函数:

usort($new, fn($a, $b) => $a['order'] - $b['order']);

诡计:您可以使用a > ba - ba <=> b上升顺序排序。对于下降顺序,只需ab的交换位置。

PHP7.4及以上版本的“箭头函数”语法:

uasort($yourArray, fn($a, $b) => $a['order'] <=> $b['order']);

漂亮的印花

echo '<pre>';print_r($yourArray);

我发现这很有帮助:

    $columns = array_column($data, "order");array_multisort($columns, SORT_ASC, $data);

按名称升序排序

正如接受的答案所述,您可以使用:

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

如果您需要按多个列排序,那么您将执行以下操作:

usort($myArray, function($a, $b) {return [$a['column1'],$a['column2']] <=> [$b['column1'],$b['column2']];});

这可以扩展到数据中的任意数量的列。这依赖于您可以直接比较PHP中的数组这一事实。在上面的示例中,数组将首先按column1排序,然后按column2排序。但是您可以按任何顺序对列进行排序,例如:

usort($myArray, function($a, $b) {return [$a['column2'],$a['column1']] <=> [$b['column2'],$b['column1']];});

如果您需要对一列升序和另一列降序进行排序,请将降序列交换到运算符<=>的另一侧:

usort($myArray, function($a, $b) {return [$a['column1'],$b['column2']] <=> [$b['column1'],$a['column2']];});
 example  with class: 
class user{private $key;
public function __construct(string $key){$this->key = $key;}
public function __invoke($a, $b){return $a[$this->key] <=> $b[$this->key];}}
$user = [['id' => 1, 'name' => 'Oliver', 'id_card' => 4444],['id' => 3, 'name' => 'Jack', 'id_card' => 5555],['id' => 2, 'name' => 'Harry', 'id_card' => 6666]];
// sort user by idusort($user, new user('id'));var_dump($user);