如何使用两列中的值对子数组进行分组,然后对第三列的值求和?

时间:2018-02-12 06:37:40

标签: php multidimensional-array sum grouping

这是我的数组的一部分:

[1] => Array
(
    [quantity] => 2
    [product_id] => 1
    [option_id] => 22
)

[2] => Array
(
    [quantity] => 2
    [product_id] => 2
    [option_id] => 22
)

[3] => Array
(
    [quantity] => 3
    [product_id] => 2
    [option_id] => 22
)

[4] => Array
(
    [quantity] => 1
    [product_id] => 2
    [option_id] => 25
)

我希望按product_idoption_id对子阵列进行分组/合并。

在合并子阵列时,我想总结quantity值。

在我的示例数据中,子阵列[2][3]都有'product_id'=>2'option_id'=>22。它们应合并为一个quantity值为5的子数组。

这是我的预期输出:

[1] => Array
(
    [quantity] => 2
    [product_id] => 1
    [option_id] => 22
)

[2] => Array
(
    [quantity] => 5
    [product_id] => 2
    [option_id] => 22
)

[3] => Array
(
    [quantity] => 1
    [product_id] => 2
    [option_id] => 25
)

*我的第一级密钥与其子阵列无关,因此可能会在此过程中更改它们。我确实希望第一级密钥从1而不是0增加。

2 个答案:

答案 0 :(得分:1)

您只需构建复合临时密钥,然后覆盖密钥。

通过编写初始元素(在这种情况下为null)然后在循环结束后删除元素,可以确保结果数组中的第一个键为1

为了避免重复的长卷复合键的“混乱”,可以将动态键保存为foreach循环内部第一行中的变量,然后在条件中的三个相应位置引用该变量块。

代码(Demo

$array = [
    1 => ['quantity' => 2, 'product_id' => 1, 'option_id' => 22],
    2 => ['quantity' => 2, 'product_id' => 2, 'option_id' => 22],
    3 => ['quantity' => 3, 'product_id' => 2, 'option_id' => 22],
    4 => ['quantity' => 1, 'product_id' => 2, 'option_id' => 25]
];

$result = [null];  // create placeholding element
foreach($array as $subarray){
    $composite_key = $subarray['product_id'] . '_' . $subarray['option_id'];
    if(!isset($result[$composite_key])){
        $result[$composite_key] = $subarray;  // first occurrence
    }else{
        $result[$composite_key]['quantity'] += $subarray['quantity'];  // not first occurrence
    }
}
$result=array_values($result);  // change from assoc to indexed
unset($result[0]);  // remove first element to start numeric keys at 1
var_export($result);

输出:

array (
  1 => 
  array (
    'quantity' => 2,
    'product_id' => 1,
    'option_id' => 22,
  ),
  2 => 
  array (
    'quantity' => 5,
    'product_id' => 2,
    'option_id' => 22,
  ),
  3 => 
  array (
    'quantity' => 1,
    'product_id' => 2,
    'option_id' => 25,
  ),
)

答案 1 :(得分:0)

您问题的一种可能解决方案包括以下步骤:

  1. 使用双for循环检查数组中的每个元素后面的每个元素。
  2. 比较产品和选项ID以及它们是否匹配。
    1. 将数量汇总到前一项。
    2. 取消设置后一项。
    3. 使用array_values再次使阵列紧凑。
    4. 打破嵌套循环。
  3. <强>代码:

    # The sample array.
    $array = [
        ["quantity" => 2, "product_id" => 1, "option_id" => 22],
        ["quantity" => 2, "product_id" => 2, "option_id" => 22],
        ["quantity" => 3, "product_id" => 2, "option_id" => 22],
        ["quantity" => 1, "product_id" => 2, "option_id" => 25]
    ];
    
    # Iterate over every element of the array.
    for ($i = 0, $l = count($array); $i < $l; $i++) {
        # Iterate over every element after the current one in the array.
        for ($j = $i + 1; $j < $l; $j++) {
            # Compare the product and option ids.
            $sameProduct = $array[$i]["product_id"] == $array[$j]["product_id"];
            $sameOption = $array[$i]["option_id"] == $array[$j]["option_id"];
    
            # Check whether two items have the same ids.
            if ($sameProduct && $sameOption) {
                # Add the value of the item at index j to the one at index i.
                $array[$i]["quantity"] += $array[$j]["quantity"];
    
                # Unset the array at index j.
                unset($array[$j]);
    
                # Make the array compact.
                $array = array_values($array);
    
                # Break out of the loops.
                break 2;
            }
        }
    }
    

    注意:您的问题表明您没有做出任何努力。我假设你完全迷失了,不知道该怎么做,这是我回答的唯一原因。如果你做了任何不能按预期工作的努力,请将它包括在你的问题中,因为这会促使其他用户回答,也许会给你更好的答案。