我有一个数组的数组:
Array (
[0] => Array (
[id] = 7867867,
[title] = 'Some Title'),
[1] => Array (
[id] = 3452342,
[title] = 'Some Title'),
[2] => Array (
[id] = 1231233,
[title] = 'Some Title'),
[3] => Array (
[id] = 5867867,
[title] = 'Some Title')
)
需要按照特定的顺序进行:
1.小行星345
1.五八六七八六七
1.七八六七八六七
1.小行星1231233
我该怎么做呢?我以前对数组进行过排序,也读过很多关于它的帖子,但它们总是基于比较的(IidoEvalueA〈valueB)。
帮助是感激不尽的。
8条答案
按热度按时间qyuhtwio1#
您可以使用
usort()
来精确指定数组的排序方式。在这种情况下,$order
数组可以在比较函数中使用。下面的示例使用
closure
使工作更轻松。此工作的关键是要比较的值是
id
在$order
数组中的位置。比较函数的工作原理是查找要比较的两个项的id在
$order
数组中的位置。则函数的返回值将为负($a
较小,因此“浮动”到顶部)。如果$a['id']
在$b['id']
之后,则函数返回一个正数($a
较大,因此“下沉”)。最后,使用闭包没有特殊的理由;这是我快速编写这些一次性函数的常用方法。它同样可以使用一个普通的命名函数。
yhxst69z2#
扩展salathe's answer以满足此附加要求:
现在,当我将项添加到数组而不是排序中时会发生什么?我不关心它们出现的顺序,只要它在我指定的项之后。
您需要在排序函数中添加两个附加条件:
1.“无关”项目必须被视为大于白名单项目
1.两个“无关”项目必须视为相等
因此,修改后的代码将是:
输出量:
06odsfpq3#
其他使用迭代调用
array_search()
的方法的答案并不像它们所能做到的那样有效。通过重新构造/翻转“order”查找数组,您可以完全省略所有array_search()
调用--使您的任务更加高效和简洁。我将使用最现代的“飞船操作符”(<=>
)、但是早期的技术对比较行的作用相同。“空合并运算符”(??
)将检查查找数组中给定id
值的存在性,检查方式与isset()
相同--这总是比X1 M6 N1 X或X1 M7 N1 X更有效。代码:(Demo)(Demo with 7.4 arrow function syntax)(Demo with lower than PHP7)
dgsult0t4#
更高效的解决方案
每次比较时不重新计算位置
当数组很大或者获取id的代价很高时,使用
usort()
可能不太好,因为每次比较都要重新计算id。尝试使用预先计算位置的array_multisort()
(参见下面示例中的mediumsort
或fastsort
),这并不复杂。另外,每次比较时在order数组中搜索id(就像在accepted answer中一样)并不能提高性能,因为每次比较都要迭代它。
在下面的代码片段中,您可以看到三个主要的排序函数:
slowsort
接受的答案。搜索每次比较的位置。
mediumsort
通过提前计算位置改进了
slowsort
fastsort
改进了
mediumsort
,避免了同时搜索。请注意,这些函数通过提供一个后备值
INF
来处理未按顺序给出id的元素。如果您的顺序数组与原始数组的id一对一匹配,则应避免将所有元素一起排序,而只需将元素插入正确的位置。我添加了一个函数cheatsort
,它正好可以做到这一点。更一般地说,您可以按权重对数组进行排序(请参阅示例中的
weightedsort
)。确保仅计算一次权重,以获得良好的性能。性能(对于长度为1000的数组)
提示:对于较大的数组,差异会变得更大。
排序函数比较
f2uvfpb95#
不用排序你也能如愿以偿。
1.如果没有重复的id,并且
$order
包含$array
中的所有id
值,并且$array
中的id
列包含$order
中的所有值,则可以通过将这些值转换为$order
中的键,然后将临时的第一级键分配给array,则将$array
合并或替换为$order
。$array
中可能有重复的ID:wgeznvg76#
@salathe对于那些很难理解salathe的usort在做什么的人:
$array中的每一项都是锦标赛中的“冠军”,将位于新数组的开始(除了他们希望成为0号而不是1号)。
$a是主场冠军,$B是比赛中的对手冠军。
来自回调的$pos_a和$pos_B是在争夺冠军a和b时将使用的属性。在本例中,该属性是$order中冠军id的索引。
然后是在返回时的战斗。现在我们看看拥有更多或更少的属性是更好的。在一个usort战斗中,主场冠军想要一个负数,这样他就可以更早地进入阵列。客场冠军想要一个正数。如果有一个0,这是一个平局。
所以下面这个比喻当消冠军属性($order中的索引)从主队属性中减去,客场冠军属性越大,获得正数获胜的可能性就越小。但是,如果你要颠倒属性的使用方式,现在主场冠军的属性从客场冠军的属性中减去。在这种情况下,客场冠军的一个更大的数字更有可能使他以一个正数结束比赛。
代码如下所示:
注意:代码运行多次,就像一个真实的的锦标赛有许多战斗,以决定谁得到第一(即0 /数组开始)
hl0ma9xz7#
如果要维护索引关联,需要定义自己的比较函数,并使用
usort
或uasort
。e0uiprwp8#
我遇到了同样的问题,@mickmackusa有我需要的答案。当有
NULL
值时,所选的答案不排序。例如:以上结果将显示以下输出:
在@mickmackusa的答案中,它不仅消除了排序中的null,而且还将排序基础中可用的第一个值放入其中,因此,由于数组中唯一可用的值是2,因此它将位于顶部。
虽然它不能在PHP 5.6中工作。所以我把它转换成PHP 5.6兼容的。这是我得到的
上述排序的结果为
我希望我的代码转换将有助于开发谁的工作在一个过时的服务器与较低的php版本。