PHP-循环遍历多维数组并在找到键时减少数组

标签 php arrays multidimensional-array

我有一个如下所示的数组:

array:3 [
  0 => array:5 [
    "id" => 18
    "product_id" => 37
    "total_price" => "643.00"
    "created_at" => "2017-05-02 13:22:35"
    "updated_at" => "2017-05-02 13:22:35"
  ]
  1 => array:5 [
    "id" => 19
    "product_id" => 36
    "total_price" => "532.00"
    "created_at" => "2017-05-02 13:23:47"
    "updated_at" => "2017-05-02 13:23:47"
  ]
  2 => array:5 [
    "id" => 20
    "product_id" => 36
    "total_price" => "532.00"
    "created_at" => "2017-05-03 13:20:47"
    "updated_at" => "2017-05-03 13:20:47"
  ]
]

在我的情况下,如果键“product_id”具有相同的值,我想减少合并这些数组并添加total_price,但我还必须将新键保存到新数组: $quantity 来存储数组的数量合并之前存在的相同 key 。 所以最终的结果应该是这样的:

array:2 [
  0 => array:5 [
    "id" => 18
    "product_id" => 37
    "total_price" => "643.00"
    "quantity"   => 1
    "created_at" => "2017-05-02 13:22:35"
    "updated_at" => "2017-05-02 13:22:35"
  ]
  1 => array:5 [
    "id" => 19
    "product_id" => 36
    "total_price" => "1064.00"
    "quantity"   => 2
    "created_at" => "2017-05-02 13:23:47"
    "updated_at" => "2017-05-02 13:23:47"
  ]
]

最初我尝试使用 array_walk_recursive,但我很困惑。

array_walk_recursive($products, function($value, $key) use (&$products_sold){
            array_push($products_sold, isset($products_sold[$key]) ?  $value + $products_sold[$key] : $value);
        });

我知道这是没用的,但我没有意识到如何做到这一点。任何解释都会有帮助。 感谢大家抽出宝贵的时间!

最佳答案

尝试

$result = array_reduce($products, function ($result, $product) {
    foreach ($result as $index => $value) {
        if ($value['product_id'] == $product['product_id']) {
            $result[$index]['total_price'] += $product['total_price'];

            return $result;
        }
    }
    $result[] = $product;
    return $result;
}, []);

但我强烈建议使用BCMath函数而不是使用 float 。

所以最好这样写

$result[$index]['total_price'] = bcadd($result[$index]['total_price'], $product['total_price'], 2);

而不是

$result[$index]['total_price'] += $product['total_price'];

更新

我们可以将上面的版本重写为嵌套 foreach,如下所示:

$reducer = function ($result, $product) {
    foreach ($result as $index => $value) {
        if ($value['product_id'] == $product['product_id']) {
            $result[$index]['total_price'] += $product['total_price'];

            return $result;
        }
    }
    $result[] = $product;
    return $result;
};

$result = [];

foreach($products as $product) {
    $result = $reducer($result, $product);
}

所以我们可以看到它只是 foreach 循环,它调用包含另一个 foreach 的函数。 我们需要另一个foreach,因为我们需要确定数组是否包含product_id 的方法。 我们可以使用product_id对结果进行索引,这样我们就可以避免第二个foreach:

$result = array_reduce($products, function ($result, $product) {
    $productId = $product['product_id'];
    if(isset($result[$productId])) {
        $result[$productId]['total_price'] += $product['total_price'];
        return $result;
    }
    $result[$productId] = $product;
    return $result;
}, []);

然后,如果您需要从零开始对索引进行排序,只需调用 array_values($result)

关于PHP-循环遍历多维数组并在找到键时减少数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44133084/

相关文章:

php - 我无法让我的登录表单与 mySQL 数据库正确连接交互

php - MySQL从文本区域插入到多行

r - 如何在R中将多维下标存储为变量

c++ - 如何将字符数组中的前 i 个字符复制到 C++ 中的另一个字符数组中?

python - 数组运算等价Python和Matlab

multidimensional-array - Chapel 中稀疏数组的稀疏切片

php - 如何替换多维数组中的键并保持顺序

javascript - 如何在 Drupal 8 主题中添加 javascript 库?

javascript - 如何在没有cronjob的情况下运行php页面脚本

javascript - 使用 settimeout 绕过地理编码查询限制