【问题标题】:PHP custom array merge on bases of same value and sum of valuePHP自定义数组基于相同值和值总和合并
【发布时间】:2016-01-22 11:13:58
【问题描述】:

我有如下数组,

Array(
    [0] => Array(
        [account] => 251234567890,
        [price] => 83
    ) [1] => Array(
        [account] => 251234567890,
        [price] => 27
    ) [2] => Array(
        [account] => 251234564526,
        [price] => 180
    ) [3] => Array(
        [account] => 251234567890,
        [price] => 40
    )
)

现在我想将数组与相同的 account 合并,并且它的总和是特定的 price

我想要这样的输出数组,

Array(
    [251234567890] => Array(
        [account] => 251234567890,
        [price] => 150
    ) [251234564526] => Array(
        [account] => 251234564526,
        [price] => 180
    )
)

我试过这样,

$res = array();
$k = 0;
foreach ($to_account as $vals) {
  if (array_key_exists($vals['account'], $res)) {
    $res[$k]['price'] += $vals['price'];
    $res[$k]['account'] = $vals['account'];
    $k++;
  } else {
    $res[$k] = $vals;
    $k++;
  }
}

因为在输入数组中只有两个唯一的 account 存在,所以输出数组应该是这两个帐户的总和

我在 herepython 中看到了类似的内容,但它希望在 python 中有所帮助,我希望在 php 中使用它有人可以在这方面帮助我

谢谢

【问题讨论】:

    标签: php arrays multidimensional-array array-merge


    【解决方案1】:

    我会分两步完成,首先按帐户键入,然后转换为您想要的输出格式:

    $data = [
      [
        'account' => 251234567890,
        'price' => 83
      ],
      [
        'account' => 251234567890,
        'price' => 27
      ],
      [
        'account' => 251234564526,
        'price' => 180
      ],
      [
        'account' => 251234567890,
        'price' => 40
      ],
    ];
    
    
    $keyed = [];
    foreach ($data as $item) {
      if (!isset($keyed[$item['account']])) {
        $keyed[$item['account']] = 0;
      }
      $keyed[$item['account']] += $item['price'];
    }
    
    $merged = [];
    foreach ($keyed as $account => $price) {
      $merged[] = compact('account', 'price');
    }
    
    print_r($merged);
    

    或者,一个更实用的解决方案(我喜欢,但有点难以理解):

    $keyed = array_reduce($data, function ($carry, $item) {
      if (!isset($carry[$item['account']])) {
        $carry[$item['account']] = 0;
      }
      $carry[$item['account']] += $item['price'];
      return $carry;
    }, []);
    
    $merged = array_map(function ($account, $price) {
      return compact('account', 'price');
    }, array_keys($keyed), $keyed);
    

    【讨论】:

      【解决方案2】:

      如果你尝试做类似的事情会怎样:

      $arr = array(
          0 => array(
              'account' => 251234567890,
              'price' => 83
          ), 1 => array(
              'account' => 251234567890,
              'price' => 27
          ), 2 =>array(
              'account' => 251234564526,
              'price' => 180
          ), 3 => array(
              'account' => 251234567890,
              'price' => 40
          )
      );
      
      foreach($arr as $key => $value) {
          $newArr[$value['account']][] = $value['price'];
      }
      
      foreach($newArr as $key => $value) {
          $finalArr[] = array('account'=>$key,'price'=>array_sum($value));
      }
      

      $finalArr:

      Array ( [0] => Array ( 
      [account] => 251234567890 
      [price] => 150 ) 
      [1] => Array ( 
      [account] => 251234564526 
      [price] => 180 ) )
      

      【讨论】:

        【解决方案3】:

        通过分配临时键,您可以确定是否处理第一次出现,然后使用适当的技术来存储整个子数组或仅向子数组的 price 元素添加值。

        代码:(Demo)

        $to_account = [
          [ 'account' => 251234567890, 'price' => 83 ],
          [ 'account' => 251234567890, 'price' => 27 ],
          [ 'account' => 251234564526, 'price' => 180 ],
          [ 'account' => 251234567890, 'price' => 40 ]
        ];
        
        foreach ($to_account as $row) {
            if (!isset($result[$row['account']])) {
                $result[$row['account']] = $row;
            } else {
                $result[$row['account']]['price'] += $row['price'];
                // imitate the above line if there was another column to sum
            }
        }
        var_export($result);
        

        输出:

        array (
          251234567890 => 
          array (
            'account' => 251234567890,
            'price' => 150,
          ),
          251234564526 => 
          array (
            'account' => 251234564526,
            'price' => 180,
          ),
        )
        

        此方法不会覆盖多余的帐户元素值。要重新索引输出数组,只需在其上调用array_values()

        【讨论】:

          【解决方案4】:

          @Jeroen 注意你的回答对我很有用,但我自己解决了这个问题,

          $final_payment_array = array();
          
          foreach ($to_account as $vals) {
               if (array_key_exists($vals['account'], $final_payment_array)) {
                      $final_payment_array[$vals['account']]['price'] += $vals['price'];
                      $final_payment_array[$vals['account']]['account'] = $vals['account'];
               } else {
                      $final_payment_array[$vals['account']] = $vals;
                 }
          }
          

          我认为这是性能方面的最佳解决方案

          谢谢

          【讨论】:

          • 这更好,但是在您编辑它之前,并没有给您您想要的确切结果,如您的问题中所述。数组的键现在是帐号,而不是 0、1 等。这就是我采用这种方法的原因。但是,如果您不关心密钥,那也没关系。
          【解决方案5】:

          这是我的解决方案。你可以试试这个

             $myArray = array(
          
                  0 => array(
                      account => 251234567890,
                      price => 83,
                      ),
          
                  1 => array(
                      account => 251234567890,
                      price => 27,
                      ),
                  2 => array(
                      account => 251234564526,
                      price => 180,
                      ),
                  3 => array(
                      account => 251234567890,
                      price => 40,
                      ),
             );
          $keyed = [];
          foreach ($myArray as $item) {
            if (!isset($keyed[$item['account']])) {
              $keyed[$item['account']] = 0;
            }
            $keyed[$item['account']] += $item['price'];
          }
          
          $merged = [];
          foreach ($keyed as $account => $price) {
            $merged[] = compact('account', 'price');
          }
          
          print_r($merged);
          

          https://eval.in/506410

          【讨论】:

          • 调用两个循环是不必要的/低效的。看我的回答。
          • @mickmackusa ok tx.
          猜你喜欢
          • 2014-02-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-03-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多