【问题标题】:PHP sort by arbitrary order [duplicate]PHP按任意顺序排序[重复]
【发布时间】:2011-08-03 16:43:06
【问题描述】:

我需要 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 时间)。由于无论如何您都必须进行排序,因此这是最佳选择。
  • 我知道这对您的问题无关紧要,但您在for 语句中有一个错误,$i&lt;count($inputArray); 用两个右括号代替了一个

标签: php arrays sorting


【解决方案1】:

PHP 提供了usort()uksort() 函数,允许您编写自己的排序例程。在这两个中,你会想要usort()

这两个函数都希望您编写一个独立的函数,它将输入数组的两个元素作为输入,并返回它们应该被排序的顺序。 usort() 函数然后运行它自己的排序算法,调用你的函数 as 来经常根据需要建立排序顺序,直到它对整个数组进行排序。

所以你会写这样的东西......

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;
}

...然后只需调用usort($inputarray,'mycompare'); 对它们进行排序。

【讨论】:

    【解决方案2】:
    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;
    }
    

    尚未测试,但试试这个。

    【讨论】:

    • 我已经修改过了,如果不行再试一下。
    【解决方案3】:

    可能比 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;
    }
    

    【讨论】:

      【解决方案4】:
      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
      • 哦,那是我搞砸了。
      猜你喜欢
      • 2018-03-29
      • 2012-07-06
      • 2012-01-11
      • 2020-07-08
      • 2015-04-29
      • 1970-01-01
      • 2017-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多