【问题标题】:PHP-Sort array based on another array?基于另一个数组的PHP排序数组?
【发布时间】:2013-06-24 15:43:05
【问题描述】:

好的,我已经在 stackoverflow 中得到了这个问题,但遗憾的是它在 javascript 中 - Javascript - sort array based on another array

我想要它在 PHP 中

$data = array(
   "item1"=>"1",
   "item2"=>"3",
   "item3"=>"5",
   "item4"=>"2",
   "item5"=>"4"
);

要匹配这个数组的排列:

sortingArr = array("5","4","3","2","1");

以及我正在寻找的输出:

$data = array(
    "item3"=>"5",
    "item5"=>"4",
    "item2"=>"3",
    "item4"=>"2",
    "item1"=>"1"
 );

知道如何做到这一点吗? 谢谢。

【问题讨论】:

  • 你可以asort()他们俩。
  • 使用usort(),具有比较$sortingArr中值位置的比较函数。

标签: php arrays sorting


【解决方案1】:

如需详细解答,为什么 array_multisort 不符合您的需求,请查看此答案: PHP array_multisort not sorting my multidimensional array as expected

简而言之:您希望根据预定义的顺序对数组进行排序。那里也给出了答案,但我也复制了一个解决方案来解决这个问题:

使用usortarray_flip,这样您就可以将您的索引数组 (ValueByPosition) 变成一个PositionByValue 数组。

    $data = array(
   "item1"=>"1",
   "item2"=>"3",
   "item3"=>"5",
   "item4"=>"2",
   "item5"=>"4"
);

usort($data, "sortByPredefinedOrder");

function sortByPredefinedOrder($leftItem, $rightItem){
  $order = array("5","4","3","2","1");

  $flipped = array_flip($order);

  $leftPos = $flipped[$leftItem];
  $rightPos = $flipped[$rightItem];
  return $leftPos >= $rightPos;   
}

print_r($data);
// usort: Array ( [0] => 5 [1] => 4 [2] => 3 [3] => 2 [4] => 1 )
// uasort: Array ( [item3] => 5 [item5] => 4 [item2] => 3 [item4] => 2 [item1] => 1 )

但是,这需要您预测预定义订单数组中所有可能的项目,或以适当的方式将其他项目串接起来。

如果您想维护关联键,请使用uasort 而不是usort

【讨论】:

    【解决方案2】:

    很简单?

    $data = array(
       "item1"=>"1",
       "item2"=>"3",
       "item3"=>"5",
       "item4"=>"2",
       "item5"=>"4"
    );
    
    $sortingArr = array("5","4","3","2","1");
    
    $result = array(); // result array
    foreach($sortingArr as $val){ // loop
        $result[array_search($val, $data)] = $val; // adding values
    }
    print_r($result); // print results
    

    输出:

    Array
    (
        [item3] => 5
        [item5] => 4
        [item2] => 3
        [item4] => 2
        [item1] => 1
    )
    

    【讨论】:

    • 我不认为这是一个很好的内存效率解决方案。在这种情况下,usort 函数更容易和更快。但这仍然是小型阵列的有效解决方案。 BR。
    • 只要这不是在应用程序的关键部分完成并且数据相当小,它将以易于理解的方式完成其工作。
    【解决方案3】:

    看我下面的 sn-p 来根据另一个数组对你的数组进行排序:

    $res_arr = array(); 
    for ($i = 0; $i < count($sortingArr); $i++) {
         for ($j = 0; $j < count($data); $j++) {
              if($data[$j] == $sortingArr[$i]) {
                 $res_arr[] = $data[$j];
                 break;
              }
         }
    }
    // $res_array is your sorted array now
    

    【讨论】:

    • 这有点晚了,但你为什么要在最后使用一个break呢?
    • 当找到对应的条目时,break 停止内部循环的进一步迭代。它可以在没有内部循环的情况下工作,但您可以节省一些额外的内部循环迭代。
    • 只有在您确定每种类型都有 1 个值的情况下才能中断,对吗?
    • 是的,正确。好点,所以如果你有多个相同点的项目,你必须删除中断
    【解决方案4】:

    我认为使用usort()the right way

    使用用户定义的比较函数按值对数组进行排序

    你可以这样做:

    $data = array(
       "item1"=>"1",
       "item2"=>"3",
       "item3"=>"5",
       "item4"=>"2",
       "item5"=>"4"
    );
    
    $sortingArr = array("5","4","3","2","1");
    
    $keys = array_flip($sortingArr);
    
    usort($data, function ($a, $b) use ($keys) {
        return $keys[$a] > $keys[$b] ? 1 : -1;
    });
    
    print_r($data);
    
    // Output
    // Array ( [0] => 5 [1] => 4 [2] => 3 [3] => 2 [4] => 1 )
    

    实时示例:https://3v4l.org/75cnu

    【讨论】:

      【解决方案5】:

      查看代码 sn-p 以进行按输入顺序排序的多维数组

      $input_format_list = [4, 1];
      $data = array(
          "0" => array(
              "School" => array(
                  "id" => 1,
                   "name" => "ST.ANN'S HIGH SCHOOL",
              )
          ),     
          "1" => array(
              "School" => array(
                  "id" => 4,
                  "name" => "JYOTI VIDHYA VIHAR",
              )
          )
      );   
      
      $result = array(); // result array
      foreach($input_format_list as $key => $value){ // loop
          foreach ($data as $k => $val) {
              if ($data[$k]['School']['id'] === $value) {
                 $result[$key] = $data[$k];
              }
          }            
      }            
      return $result;
      

      【讨论】:

        【解决方案6】:

        我为我的解决方案感到非常自豪:

        uasort($data, function($a, $b) use ($sortingArr) {  
            return array_search($a, $sortingArr) <=> array_search($b, $sortingArr);
        });
        

        工作示例:https://3v4l.org/bbIk2

        1. 它使用uasort 来维护OP 请求的键值关联。 (不像@hassan 的其他优雅的解决方案)
        2. 不要求 $data 数组中的每个元素都出现在排序数组中。 (就像@HamZa 的解决方案)
        3. 很简短。
        4. 它使用宇宙飞船运算符&lt;=&gt; 进行比较,而不是更冗长的逻辑。

        代码:

        【讨论】:

          【解决方案7】:

          看看array_multisort。我不完全确定如何使用它,因为我从未找到它的实际用途(我更喜欢使用usort 来明确定义我的术语),但它可能对你有用。

          【讨论】:

          • 我不认为array_multisort() 能满足他的需要。它会对一个数组进行正常排序,然后对另一个数组进行相应的重新排序。
          • 因此,如果第一个数组是包含所需顺序的数组,那是否意味着将 $data 数组作为第二个数组相应地对其进行排序...?我不知道,就像我说的,从未使用过该功能!
          • 我也没有用过,但是文档页面上的示例似乎与他想要的不符。查看示例 #1。它不会按原始顺序保留任何输入。
          • 我用它来根据用户输入对表格进行排序,它肯定是一个奇怪的功能,但有时很有用,我可以发布一个示例,但恐怕它与您的问题没有直接关系
          • 查看我的帖子以了解数组多重排序的工作原理。不,它不会工作。 array_multisort 将对数组进行“排序”,定义顺序并将其他数组的条目相对向上或向下移动。这里不需要。
          【解决方案8】:
          <?php 
          $data = array(
             "item1"=>"1",
             "item2"=>"3",
             "item3"=>"5",
             "item4"=>"2",
             "item5"=>"4"
          );
          $result=array_flip($data);
          
          krsort($result);
          
          $result=array_flip($result);
          
          print_r($result);
          
          //use rsort for the index array
          
          $sortingArr = array("5","4","3","2","1");
          
          print_r($sortingArr);
          

          【讨论】:

          • 按值对$data 的值进行排序确实没有意义。因为$sortingArr 可能不是递减值。同样使用array_flip 然后krsort 只是丑陋的,你可以直接使用rsort
          • $sortingArr 也使用 rsort 按降序排序。两个数组现在都可以降序使用
          猜你喜欢
          • 2014-10-25
          • 1970-01-01
          • 2021-07-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-25
          • 2019-05-02
          相关资源
          最近更新 更多