【问题标题】:Multidimensional Array delete duplicated key values with condition多维数组删除有条件的重复键值
【发布时间】:2018-02-01 09:24:20
【问题描述】:

我有一个这样的数组:

$ratesData = [
    1 => [
        'id' => 1,
        'amount' => 2
    ],
    0 => [
        'id' => 1,
        'amount' => 1
    ],
    2 => [
        'id' => 1,
        'amount' => 3
    ],
    3 => [
        'id' => 2,
        'amount' => 2
    ]
];

我想以最便宜的数量保留重复的 id 数组,结果将是这样的:

[
    0 => [
       'id' => 1,
       'amount' => 1
    ],
    1 => [
       'id' => 2,
       'amount' => 2
    ]
]

我有一个代码可以解决这个问题,但我正在寻找一种优雅的方式来完成这个,而不需要所有这些循环:

    foreach($ratesData as $firstLoopKey => $firstLoopValue) {
        foreach($ratesData as $secondLoopKey => $secondLoopValue) {
            if($firstLoopValue['id'] === $secondLoopValue['id'] && $firstLoopKey != $secondLoopKey ) {
                if ($ratesData[$secondLoopKey]['total_amount'] > $ratesData[$firstLoopKey]['total_amount']) {
                    $deleteElements[] = $secondLoopKey;
                }
            }
        }
    }

    if (isset($deleteElements)) {
        foreach ($deleteElements as $element) {
            unset($ratesData[$element]);
        }
    }

    $ratesData = array_values($ratesData);

    return $ratesData;

【问题讨论】:

    标签: php arrays loops multidimensional-array


    【解决方案1】:

    您可以按amount 降序排序,然后按id 提取数组索引,这将消除amount 最低的重复项,覆盖较高的:

    array_multisort(array_column($ratesData, 'amount'), SORT_DESC, $ratesData);
    $ratesData = array_column($ratesData, null, 'id');
    

    产量:

    Array
    (
        [1] => Array
            (
                [id] => 1
                [amount] => 1
            )
        [2] => Array
            (
                [id] => 2
                [amount] => 2
            )
    )
    

    我总是喜欢将键与唯一的 id 相同,以使数组访问/排序更容易,但如果需要,您可以重新索引:

    $ratesData = array_values($ratesData);
    

    【讨论】:

      【解决方案2】:

      一些简单的解决方案:

      // your source array
      $ratesData = [];
      // result array
      $filtered = [];
      
      foreach ($ratesData as $v) {
          $id = $v['id'];
          // if this is `$id`, which is not in `$filtered` yet
          // or value of `$filtered[$id]['amount']` is greater then current `$v`
          // then replace `$filtered[$id]` with current `$v`
          if (!isset($filtered[$id]) || $filtered[$id]['amount'] > $v['amount']) {
              $filtered[$id] = $v;
          }
      }
      
      echo'<pre>',print_r(array_values($filtered)),'</pre>';
      

      【讨论】:

        【解决方案3】:

        另一个很好的解决方案

            $uniqueRates = [];
        
            foreach ($ratesData as $rateData) {
                $key = $rateData['id'];
                if (!\array_key_exists($key, $uniqueRates) ||
                    $rateData['total_amount'] < $uniqueRates[$key]['total_amount']
                ) {
                    $uniqueRates[$key] = $rateData;
                }
            }
        
            return array_values($uniqueRates);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-12-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-05
          • 2019-03-18
          • 2017-01-01
          相关资源
          最近更新 更多