I have an array that looks like this:
我有一個這樣的數組:
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"
]
]
In my case if the key "product_id" has the same value I want to reduce merge those arrays and add the total_price but I have to also save a new key to the new array: $quantity to store the number of array with the same key that existed before merging. So the final result should look like this:
在我的例子中,如果關鍵字“product_id”具有相同的值,我想減少合並這些數組並添加total_price,但是我還必須為新數組保存一個新鍵:$quantity,以使用合並前存在的相同鍵來存儲數組的數量。所以最終的結果應該是這樣的:
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"
]
]
Initially I tried with array_walk_recursive, but I got confused.
最初我嘗試使用array_walk_recursive.com,但是我搞混了。
array_walk_recursive($products, function($value, $key) use (&$products_sold){
array_push($products_sold, isset($products_sold[$key]) ? $value + $products_sold[$key] : $value);
});
I know this is useless but I failed to realize how to do this. Any explanation would be helpful. Thank you all for your time!
我知道這是沒有用的,但我沒有意識到怎么做。任何解釋都是有用的。謝謝大家!
2 个解决方案
#1
2
Try
試一試
$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;
}, []);
But I strongly recomment use BCMath functions instead of working with floats.
但我強烈建議使用BCMath函數,而不是使用浮點數。
So its better to write
所以最好寫下來
$result[$index]['total_price'] = bcadd($result[$index]['total_price'], $product['total_price'], 2);
instead of
而不是
$result[$index]['total_price'] += $product['total_price'];
Update
更新
We can rewrite above version to nested foreach like so:
我們可以將上面的版本重寫為嵌套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);
}
so we can see it is just foreach loop which calls function which contains another foreach. We need another foreach because we need the way to determine if array contains product_id. We can index result with product_id so we can avoid secind foreach:
我們可以看到它只是foreach循環它調用包含另一個foreach的函數。我們需要另一個foreach,因為我們需要確定數組是否包含product_id。我們可以用product_id索引結果因此我們可以避免secind 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;
}, []);
and then if you need indexes to be ordered from zero just call array_values($result)
如果需要從0開始排序索引只需調用array_values($result)
#2
2
Got it done! I should say I didnt use total_price as string so I can do addition.
做到了!我應該說,我沒有使用total_price作為字符串,所以我可以添加。
$stuff = array(
array(
"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"),
array(
"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"),
array(
"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")
);
for ($i=0; $i < count($stuff); $i++) {
$product_id = $stuff[$i]["product_id"];
foreach ($stuff as $key => $value) {
if($value["product_id"] === $product_id && $i !== $key) {
$stuff[$i]["total_price"] += $value["total_price"];
unset($stuff[$key]);
}
}
}