按任意顺序排序的PHP

7
我需要一个在php中根据任意顺序对单词列表进行排序的函数。
列表中任何不在我预定义顺序中的单词应按字母顺序排在列表末尾。
以下是我的第一次尝试,它既不优雅也不高效。你能否提供更好的实现方式?
谢谢
public static function sortWords(&$inputArray){
    $order=array("Banana","Orange", "Apple", "Kiwi");
    sort($inputArray);
    for($i=0;$i<count($inputArray));$i++){
        $ac = $inputArray[$i];
        $position = array_search($ac,$order);
        if($position !== false && $i != $position){
            $temp=$inputArray[$position];
            $inputArray[$position]=$inputArray[$i];
            $inputArray[$i]=$temp;
        }
    }
}

你可以先对这两个列表进行排序(时间复杂度为NlogN + MlogM),然后遍历列表找出匹配项(时间复杂度为N+M)。由于你必须进行排序,所以这是最优解。 - user684934
我知道这对你的问题来说并不重要,但是在for语句中你有一个错误,应该只有一个右括号而不是两个,正确的写法是$i<count($inputArray); - AJJ
4个回答

13

PHP提供了 usort()uksort() 函数,允许您编写自己的排序程序。其中,您需要使用 usort()

这两个函数都要求您编写一个独立的函数,该函数以输入数组的两个元素作为输入,并返回它们应该排序的顺序。然后,usort() 函数运行自己的排序算法,根据需要多次调用您的函数来确定排序顺序,直到对整个数组进行排序。

因此,您可以编写类似以下代码的内容...

function mycompare($a, $b) {
    if ($a == $b) {return 0;}
    $order=array("Banana","Orange", "Apple", "Kiwi");
    $position = array_search($a,$order);
    $position2 = array_search($b, $order);

    //if both are in the $order, then sort according to their order in $order...
    if ($position2!==false && $position!==false) {return ($position < $position2) ? -1 : 1;}
    //if only one is in $order, then sort to put the one in $order first...
    if($position!==false) {return -1;}
    if($position2!==false) {return 1;}

    //if neither in $order, then a simple alphabetic sort...
    return ($a < $b) ? -1 : 1;
}

如果你已经编写了一个自定义的比较函数mycompare,那么只需要调用usort($inputarray,'mycompare');来对数组进行排序。


1
public static function sortWords($inputArray){
    $order=array("Banana","Orange", "Apple", "Kiwi");
    $sorted_array = array_diff($inputArray,$order);
    sort($sorted_array);
    $rest_array = array_intersect($order,$inputArray);    
    $result = array_merge($rest_array,$sorted_array);
    return $result;
}

还没有测试,但可以试试这个。


我已经编辑过了,请再试一次。 - Headshota

1

可能比Headshota的解决方案慢一些,但只是为了提供另一种(未经测试的)可能性:

function sortWordsCmp($a, $b) {
  $order=array("Banana","Orange", "Apple", "Kiwi");
  $a = array_search($a, $order);
  $b = array_search($b, $order);

  if ($a === $b)
    return 0;

  return (($b===false) || ($a < $b)) ? -1 : +1;
}

public static function sortWords($inputArray){
  usort($inputArray, 'sortWordsCmp');
  return $inputArray;
}

0
public static function sortByArbitraryKeys(&$inputArray, $sort_order) {
    $sort_order = array_flip($sort_order);
    uksort($inputArray, function ($a, $b) use ($sort_order) {
        return $sort_order[$a] - $sort_order[$b];
    }
}

所以一个例子如下...

// Doe, John L.
$this->full_name = ['last_name'=>'Doe', 'first_name'=>'John', 'middle_initial'=>'L.'];

// John L. Doe
$this->sortByArbitraryKeys($this->full_name, ['first_name', 'middle_initial', 'last_name']);

你可以轻松地重构它以适应你特定的使用情况。


$sort_array是什么? - crmpicco
哦,那是我搞砸了。 - kjg61pt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接