我需要实现一些特定的排序算法。我有两个数组:
$items = array(
array("id" => "…", "type" => "alpha"),
array("id" => "…", "type" => "beta"),
array("id" => "…", "type" => "company"),
array("id" => "…", "type" => "marketing"),
array("id" => "…", "type" => "beta"),
array("id" => "…", "type" => "company"),
array("id" => "…", "type" => "alpha"),
array("id" => "…", "type" => "alpha"),
array("id" => "…", "type" => "company"),
array("id" => "…", "type" => "marketing"),
[…]
);
$order = array("company", "marketing", "alpha", "beta" );
正如您可能想象的那样,我需要根据$items
中指定的顺序对$order
进行排序。
答案 0 :(得分:4)
运行$items
并使用“type”作为键将所有内容索引到字典中。然后运行$order
并查找与该“类型”对应的项目列表,并将它们附加到排序列表中。在O(n+k)
中运行,k为|order|
。
答案 1 :(得分:3)
您可以使用usort
usort($items, "cmp");
function cmp($a, $b)
{
$order = array("company" => 0, "marketing" => 1, "alpha" => 2, "beta" => 3);
$order_a = $order[$a["type"]];
$order_b = $order[$b["type"]];
if ($order_a == $order_b) {
return 0;
}
return ($order_a < $order_b) ? -1 : 1;
}
答案 2 :(得分:2)
与Ozgur非常相似!!但是,我将构建功能来处理订单中未考虑的意外值。它们放在排序数组的末尾。
usort($items,"compare");
echo "<pre>";
print_r($items);
echo "</pre>";
function compare($a, $b) {
$order = array("company" => 1, "marketing" => 2, "alpha" => 3, "beta" => 4);
$ax = $order[$a['type']]; $bx = $order[$b['type']];
if ($ax < 1) return 1;
if ($ax == $bx) return 0;
return ($ax > $bx) ? 1 : -1;
}
答案 3 :(得分:1)
使用usort,这是一种高效的PHP算法,可以根据您提供的条件运行。
http://php.net/manual/en/function.usort.php
这是一个正在运行的代码,您可以根据您的数据对其进行基准测试: http://codepad.org/MRpZQkKk
如果你想改变排序标准,这会给你更多的控制权, 也很复杂,它很快,应该是O(n log n)(内部快速排序), 空间复杂度也很低。
以下是更多信息: Which sort algorithms does PHP's usort apply?
<?php
$items = array(
array("id" => "…", "type" => "alpha"),
array("id" => "…", "type" => "beta"),
array("id" => "…", "type" => "company"),
array("id" => "…", "type" => "marketing"),
array("id" => "…", "type" => "beta"),
array("id" => "…", "type" => "company"),
array("id" => "…", "type" => "alpha"),
array("id" => "…", "type" => "alpha"),
array("id" => "…", "type" => "company"),
array("id" => "…", "type" => "marketing"),
);
$order = array("company", "marketing", "alpha", "beta" );
$orderIndexes = array(); /* cache indexes of the order keys */
for($i = 0 ; $i < count($order) ; $i++ )
{
$orderIndexes[$order[$i]] = $i ;
}
/* we have something like :
$orderIndexes = array('company' => 0 , 'marketing' => 1 , ....);
*/
function myCriteria($item1,$item2) /* this is the function used to decide order */
{ global $orderIndexes;
$index1 = $orderIndexes[$item1['type']];
$index2 = $orderIndexes[$item2['type']];
return $index1 - $index2 ; // negative means $item1 precedes $item2
}
usort($items,"myCriteria");
print_r($items);
?>
答案 4 :(得分:1)
您可以实现用户排序功能的简单实现:
function mySort($a, $b) {
global $order;
return array_search($a['type'], $order) - array_search($b['type'], $order);
}
然后执行usort()
:
usort($items, 'mySort');
可能效率不高,但works。
<强>更新强>
为了避免多次调用array_search()
,您可以事先翻转$order
数组。这将通过简单的查找替换array_search()
:
$reversed_order = array_flip($order);
function mySort($a, $b) {
global $reversed_order;
return $reversed_order[$a['type']] - $reversed_order[$b['type']];
}
应该更有效率。 (demo)