How to Sort Multi-dimensional Array by Value?
如何根据"order"键的值对该数组进行排序?尽管这些值当前是连续的,但它们并不总是连续的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 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
)
) |
- 交叉链接:参考:用PHP对数组和数据进行排序的所有基本方法
尝试使用usort,如果您仍然使用php 5.2或更早版本,则必须首先定义排序函数:
1 2 3 4 5
| function sortByOrder ($a, $b) {
return $a['order'] - $b['order'];
}
usort($myArray, 'sortByOrder'); |
从php 5.3开始,可以使用匿名函数:
1 2 3
| usort($myArray, function($a, $b) {
return $a['order'] - $b['order'];
}); |
最后,使用php 7,您可以使用spaceship操作符:
1 2 3
| usort($myArray, function($a, $b) {
return $a['order'] <=> $b['order'];
}); |
要将此扩展到多维排序,请参考第二/第三排序元素(如果第一个为零),最好在下面解释。您还可以使用它对子元素进行排序。
1 2 3 4 5 6 7 8 9 10
| 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()—请参见手册中的数组排序功能比较。
- 我的措词有点不对劲,我会修改的。我的意思是,如果您不在php 5.3上,您需要为这个特殊的排序创建一个特殊的函数(这在某种程度上不是很优雅)。否则,您可以在这里使用匿名函数。
- @乔纳森:你看不到PHP所做的大部分工作。它接受数组并从两个元素开始,然后将其传递给这个用户定义的函数。然后,函数负责比较它们:如果第一个元素大于第二个元素,则返回一个正整数;如果它小于,则返回一个负整数。如果是equel,则返回0。然后,PHP将另外两个元素发送到您的函数中,并继续这样做,直到对数组进行排序。这里的函数很短,如果不比较整数,它可能会复杂得多。
- 在我的例子中,你的解决方案是错误的。第一列被排除在排序之外。你能查一下吗?
- Protip:如果要保留数组键,请使用uasort()。
- 如果可排序的值是十进制数,请小心。如果排序函数get的$a=1和$b=0.1,则差异为0.9,但函数返回一个int,在本例中为0,因此$a和$b被认为是相等的,并且排序错误。比较A美元是否大于B美元或等于B美元更可靠,并相应地返回-1、1或0。
- 这很好,我有一个多维数组要排序。而且效果很好!我就是这样用的。
- 如果你把这个键作为一个常量,那就太好了。Lohoris的解决方案以密钥作为变量,使函数更加抽象和可重用。
- 我花了一段时间才知道。要对逆序(desc)进行排序,您可以切换$A和$B。因此$B["order"]-$A["order"]
- 为什么需要php5.3或更高版本?
- @craphunter:php5.2版本也适用于php5.3,只是不那么优雅。
- 对于要排序的数组的任何元素:$name='order';//定义了用于排序的名称usort($myarray,函数($a,$b)use(&;$name)返回$a[$name]-$b[$name];);
- 我混淆了$A和$B数组。从中,SortByOrder($A$B)函数将接收$A和$B。
- 最有趣的是,认为这个不起作用的usort(@$MyArray,函数($A,$B),,,为什么usort不喜欢(at)
- 嗨,伙计们,我是PHP新手,有人能给我解释一下吗,这行=>返回$A["order"]-$B["order"];它是减法还是比较法?
- @Vinothkumar请阅读第四条评论,了解这里到底发生了什么。
- @克里斯蒂安斯塔德:谢谢你……我真的有一段时间脑子坏了……现在我明白了。正、负和零。令人惊叹的。。。
- 在CodeIgniter中,我收到警告>usort()要求参数2是有效的回调、找不到函数"sortByOrder"或函数名无效
- 工作得很有魅力。注意:如果您想进一步对数组中的项进行排序,您可以这样做,它将正确地移动所有项:d usort($mile2['milestones'], function($a, $b) { return $a['start_time']['date'] - $b['start_time']['date']; });。
- 哈!我喜欢宇宙飞船操作员的结局。很棒的工作。
- @谢谢!我想知道我的keyed数组在usort()之后发生了什么。uasort()的工作方式很有魅力。
- 我一直在使用普通的香草"排序"我的结构没有任何"明显"的问题。我认为这可能是"运气",因为一旦我的阵列变大,订购就会变得疯狂。上述解决方案在缓解压力时效果很好@
- 对于字符串值的排序,请使用:{return strcmp(strtolower($a['order_string']), strtolower($b['order_string']));}(它是StackOverflow上某人的答案,但它的正确位置在这里)。
- 宇宙飞船操作员+1
- 我的嘴还开着,谢谢这个简单的魔法答案。我用这个订购function sortByOrder($a, $b) { return $b[1] - $a[1]; } usort($anahtarlar, 'sortByOrder');。
- 你还需要什么,真是太棒了。
- 小心使用return $a['dummy'] - $b['dummy']:用这些阵列试试:$array = []; $array[] = array("dummy" => -10.19); $array[] = array("dummy" => -10.05); $array[] = array("dummy" => -10.21);尽可能使用宇宙飞船操作员或return (floatval($a['dummy']) < floatval($b['dummy'])) ? -1 : 1;。
- 你救了我的命,谢谢
- 感谢您的惠顾。
- 我的服务器上有PHP7,但我仍在使用:Parse error: syntax error, unexpected '>' in ...将宇宙飞船更改为"减号"——不会产生正确的排序。
- 谢谢@marco-你的解决方案是救命稻草!
- 不要使用第二个脚本(usort($myArray, function($a, $b) { return $a['order'] - $b['order']; });)。因为阅读这个问题stackoverflow.com/questions/50636981/&hellip;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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"); |
- @noc2spam我很乐意帮忙,但请考虑遵循studer的建议,这可能更有效,更整洁!
- @Lohoris肯定,伙计,我也在检查。如果我找不到这个问题,昨天在办公室会是一个艰难的一天。
- 嗯,不能再加一个答案了。我把它放在这里是因为我不需要那些愚蠢的点:所以对于多维排序,它(几乎)是相同的东西(srry你必须复制粘贴并重新格式化它):函数aasort(&;$array,$key1,$key2,$key3)$sorter=array();$ret=array();reset($array);foreach($array as$ii=>$va)$sorter[$ii]=getprice($va[$key1][$key2][$key3]);}arsort($sorter);foreach($sorter as$ii=>$va)$ret[$ii]=$array[$ii];$array=$ret;
- 比上面的答案更容易应用
- 适用于PHP5.9
我使用这个函数:
1 2 3 4 5 6 7 8 9 10 11
| 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,因此不需要预先分配$sort_col,从而节省时间和内存。
- 对我来说很好,但是…为什么需要指定&$arr,而不是仅指定$arr?
- @radumurzea,因此数组是通过引用传递的,可以由函数修改,而不是由接收副本的函数修改
- 这也适用于浮动柱。
- 这是区分大小写的,将保留一些条目未排序。
- 这是一个更好的解决方案,因为USORT非常慢!
- @汤海也为我工作得很好。只是想知道它是否能很好地工作,在案件的否定号以及。
- 缺少返回$arr;到您的函数?谢谢。
- @ AdrianP。:数组是通过引用传递的,因此它将修改传递的数组,而不是返回已排序的副本。
- 当然,最好的选择。它非常灵活。我们可以很容易地按特定键排序,并定义顺序asc或desc。神奇的解决方案,tks!
- 很好的功能,它还保留了基数组中的键,这是一个很大的优点。
- 简单有效。
我通常使用usort,并通过自己的比较函数。在这种情况下,非常简单:
1 2 3 4 5
| function compareOrder ($a, $b)
{
return $a['order'] - $b['order'];
}
usort($array, 'compareOrder'); |
- 该死,我慢了30秒。但不是A-B美元吗?
- 我总是错的。让我从手册中想一想:如果第一个参数小于第二个参数,则返回值必须小于零。所以如果$a['order']是3,$b['order']是6,我会返回-3。对的?
- 好吧,你还B-A,那就3分了。因此分类错误。
- 啊。好啊。我使用的是非逻辑算术,你头脑中的想法与你所产生的单词不匹配。这项研究最常在星期五下午进行。
- 在某些情况下,上面的答案是返回错误的结果。参考stackoverflow.com/questions/50636981/&hellip;
1 2 3
| $sort = array();
$array_lowercase = array_map('strtolower', $array_to_be_sorted);
array_multisort($array_lowercase, SORT_ASC , SORT_STRING , $alphabetically_ordered_array); |
这将同时处理大写和小写字母。
实现这一目标的一种方法是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| $new = [
[
'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4',
'title' => 'Flower',
'order' => 3,
],
[
'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594',
'title' => 'Free',
'order' => 2,
],
[
'hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b',
'title' => 'Ready',
'order' => 1,
],
];
$keys = array_column ($new, 'order');
$result = array_multisort($keys, SORT_ASC , $new); |
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 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
)
) |
要按"标题"键的值对数组进行排序,请使用:
1 2 3
| uasort($myArray, function($a, $b) {
return strcmp($a['title'], $b['title']);
}); |
strcmp比较字符串。
uasort()按照定义维护数组键。
最灵活的方法是使用这种方法
1
| Arr ::sortByKeys(array $array, $keys, bool $assoc = true): array |
这就是为什么:
可以按任意键排序(也可以嵌套,如'key1.key2.key3'或['k1', 'k2', 'k3'])
同时适用于关联数组和非关联数组($assoc标志)
它不使用引用-返回新的排序数组
在您的情况下,它将简单如下:
1
| $sortedArray = Arr::sortByKeys($array, 'order'); |
此方法是此库的一部分。
让我们面对现实:PHP没有一个简单的开箱即用的函数来正确处理每个数组排序场景。
这个程序是直观的,这意味着更快的调试和维护:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| // automatic population of 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 example
while($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);
}
} |
- "让我们面对现实:PHP没有一个简单的开箱即用的函数来正确处理每个数组排序方案。"这正是usort/ksort/asort为^ ^设计的功能。
- QED。谢谢你的支持。;)
- 实际上,PHP有很多排序函数,可以用来处理每个数组排序场景。
- 请举例说明!!!!TKS