Get total sum of repeating IDs stored in multidimensional array - php

I have a multidimensional array of items added to cart in codeigniter. Lets say I order food for me and several friends (specific IDs stored in next level array). Now in case someone has more items I need to get total sum of each friend and save it as money owned to me. How to loop all items to get total sum of each friend with same ID (I cannot move the friend ID to parent array). I store them to database in a way we can see in the table below in non-repeating way. I need a new array to get results like this(to store/update them).
friend_id
amount_owned
52
35
28
5
friend_id 0 is me...we skip me != 0
Array
(
[array] => Array
(
[carthashid1] => Array
(
[0] => Array
(
[foodid] => 322
[price] => 5
[name] => Chicken Burger
[options] => Array
(
[friend_id] => 52
[special_instructions] =>
)
[rowid] => ceec8698316fe95ec9d7dccf961f32c1
[num_added] => 5
[sum_price] => 25
)
[1] => Array
(
[foodid] => 323
[price] => 5
[name] => Beef Burger
[options] => Array
(
[friend_id] => 52
[special_instructions] =>
)
[rowid] => c2d1c15d159123d1cbdce967785ef06e
[num_added] => 2
[sum_price] => 10
)
[2] => Array
(
[foodid] => 322
[price] => 5
[name] => Chicken Burger
[options] => Array
(
[friend_id] => 28
[special_instructions] =>
)
[rowid] => 3daa7b14b23a5c0afa9b196ea6e35227
[num_added] => 1
[sum_price] => 5
)
[3] => Array
(
[foodid] => 323
[price] => 5
[name] => Beef Burger
[options] => Array
(
[friend_id] => 0
[special_instructions] =>
)
[rowid] => 734c9cc82cf35e2dcc42f28d96a8ebde
[num_added] => 1
[sum_price] => 5
)
)
)
[finalSum] => 45
[finalItemsCount] => 9
)

It would have taken me less time to check my answer if I didnt have to Hand Code the array, but here it is anyway
$input = [
'array' => [
'carthashid1' => [
[
'foodid' => 322, 'price' => 5,
'name' => 'Chicken Burger',
'options' => ['friend_id' => 52, 'special_instructions' => ''],
'rowid' => 'ceec8698316fe95ec9d7dccf961f32c1', 'num_added' => 5,'sum_price' => 25
],
[
'foodid' => 322, 'price' => 5,
'name' => 'Beef Burger',
'options' => ['friend_id' => 52,'special_instructions' => ''],
'rowid' => 'ceec8698316fe95ec9d7dccf961f32c1', 'num_added' => 2,'sum_price' => 10
],
[
'foodid' => 322,'price' => 5,'name' => 'Chicken Burger',
'options' => ['friend_id' => 28,'special_instructions' => ''],
'rowid' => 'ceec8698316fe95ec9d7dccf961f32c1', 'num_added' => 1,'sum_price' => 5
],
[
'foodid' => 322, 'price' => 5, 'name' => 'Beef Burger',
'options' => ['friend_id' => 0,'special_instructions' => ''],
'rowid' => 'ceec8698316fe95ec9d7dccf961f32c1', 'num_added' => 1, 'sum_price' => 5
]
]
]
];
$friends = [];
foreach($input['array']['carthashid1'] as $ordered){
if ($ordered['options']['friend_id'] == 0) {
// its me, ignore me
continue;
}
if ( ! isset($friends[$ordered['options']['friend_id']]) ) {
// initialise the accumulator for this friend
$friends[$ordered['options']['friend_id']] = 0;
}
$friends[$ordered['options']['friend_id']] += $ordered['sum_price'];
}
print_r($friends);
RESULT
Array
(
[52] => 35
[28] => 5
)

You could theoretically do entire task in single DB query, also the friend_id can be moved to parent array by modifying DB query.
Slightly different approach to keep friend_id, amount_owned structure:
$owned = [];
foreach($arr['array']['carthashid1'] as $item){
if(isset($item['options']['friend_id']) && $item['options']['friend_id'] != 0)
{
if(count($owned) && ($key = array_search($item['options']['friend_id'], array_column($owned, 'friend_id'))) !== false){
// we found friend id in array lets add the price:
$owned[$key]['amount_owned'] += $item['sum_price'];
continue;
}
// when we dont find the friend id in array create that item here:
$owned[] = ['friend_id' => $item['options']['friend_id'], 'amount_owned' => $item['sum_price']];
}
}
print_r($owned);
Result:
Array
(
[0] => Array
(
[friend_id] => 52
[amount_owned] => 35
)
[1] => Array
(
[friend_id] => 28
[amount_owned] => 5
)
)

Related

sum value in foreach loop based on another value php

I have an array like below. There are id, label, cost, and cid in an array. We want to sum the cost based on the cid like for cid 22 cost should be 196.5 and for cid 11 cost should be 44.4. In our out put array we want to keep the label, cost (sum), and cid, Please see expected output array.
Array
(
[0] => Array
(
[id] => 1331
[label] => PM1
[cost] => 98.25
[cid] => 22
[product_id] => 133
)
[1] => Array
(
[id] => 1332
[label] => PM3
[cost] => 22.20
[cid] => 11
[product_id] => 133
)
[2] => Array
(
[id] => 1341
[label] => PM1
[cost] => 98.25
[cid] => 22
[product_id] => 134
)
[3] => Array
(
[id] => 1342
[label] => PM3
[cost] => 22.20
[cid] => 11
[product_id] => 134
)
)
Tried below
foreach ($array $key => $value) {
$final[$value['cid']] += $value['cost'];
}
print_r ($final);
Getting below as an output
Array
(
[22] => 196.5
[11] => 44.4
)
Want expected output like below.
Array
(
[22] => Array
(
[label] => PM1
[cost] => 196.5
[cid] => 22
)
[11] => Array
(
[label] => PM3
[cost] => 44.4
[cid] => 11
)
)
Basically want to sum cost based on cid and want to keep the label, cost (sum), and cid.
Any help will be greatly appreciated.
I believe this should do the trick
$CIDs_identified = array();
$final_array = array();
foreach($original_array as $small_array){
if(!in_array($small_array['cid'], $CIDs_identified)){
$CIDs_identified[] = $small_array['cid'];
$final_array[$small_array['cid']] = array(
'label' => $small_array['label'],
'cost' => $small_array['cost'],
'cid' => $small_array['cid'],
);
}else{
$final_array[$small_array['cid']]['cost'] += $small_array['cost'];
}
}
On this site, if you can provide your source array in usable format, that is really helpful so that we don't have to retype it. One way to do that is using var_export.
Below is a simple version. Create an array indexed by cid. If that item doesn't exist, populate it with the basic data and a zero cost. Then on each loop, including the initial, add the row's cost.
<?php
$data = [
[
'id' => 1331,
'label' => 'PMI',
'cost' => 98.25,
'cid' => 22,
'product_id' => 133,
],
[
'id' => 1341,
'label' => 'PMI',
'cost' => 98.25,
'cid' => 22,
'product_id' => 134,
],
];
$output = [];
foreach ($data as $item) {
if (!isset($output[$item['cid']])) {
$output[$item['cid']] = [
'label' => $item['label'],
'cost' => 0,
'cid' => $item['cid'],
];
}
$output[$item['cid']]['cost'] += $item['cost'];
}
print_r($output);
Demo here: https://3v4l.org/MY6Xu
$list = [
[ 'id' => 1331, 'label' => 'PM1', 'cost' => 98.25, 'cid' => 22, 'product_id' => 133 ],
[ 'id' => 1332, 'label' => 'PM3', 'cost' => 22.20, 'cid' => 11, 'product_id' => 133 ],
[ 'id' => 1341, 'label' => 'PM1', 'cost' => 98.25, 'cid' => 22, 'product_id' => 134 ],
[ 'id' => 1342, 'label' => 'PM3', 'cost' => 22.20, 'cid' => 11, 'product_id' => 134 ]
];
$result = [];
array_walk($list, function ($item) use (&$result) {
if (isset($result[$item['cid']])) {
$result[$item['cid']]['cost'] = $item['cost'] + $result[$item['cid']]['cost'];
} else {
$result[$item['cid']] = [ 'label' => $item['label'], 'cost' => $item['cost'], 'cid' => $item['cid'] ];
}
});
print_r($result);
Output:
Array
(
[22] => Array
(
[label] => PM1
[cost] => 196.5
[cid] => 22
)
[11] => Array
(
[label] => PM3
[cost] => 44.4
[cid] => 11
)
)

sum array indexes with same value for a specific key

I have the following array:
[0] => Array
(
[id] => 1
[uid] => 50
[sum1] => 1
[sum2] => 2
)
[1] => Array
(
[id] => 2
[uid] => 50
[sum1] => 2
[sum2] => 4
)
[2] => Array
(
[id] => 3
[uid] => 51
[sum1] => 3
[sum2] => 5
)
As you can see, on some of those indexes, [uid] is the same. The length and data of the array is dynamic.
what i need to do is merge the indexes that have the same value for[uid] and sum the values for the other keys:
[0] => Array
(
[id] => 2
[uid] => 50
[sum1] => 3
[sum2] => 6
)
[1] => Array
(
[id] => 3
[uid] => 51
[sum1] => 3
[sum2] => 5
)
But for the life of me, i can't figure out how to do that.
Any help appreciated!
You can do it like this way,
<?php
$mainArray = [
0 => Array
(
'id' => 1,
'uid' => 50,
'sum1' => 1,
'sum2' => 2
),
1 => Array
(
'id' => 2,
'uid' => 50,
'sum1' => 2,
'sum2' => 4
),
2 => Array
(
'id' => 3,
'uid' => 51,
'sum1' => 3,
'sum2' => 5
)
];
$newArray=[];
foreach ($mainArray as $value) {
if(!array_key_exists($value['uid'], $newArray)){
// Store first time
$newArray[$value['uid']] = $value;
}else{
// Already exist, then sum and replace it
$newArray[$value['uid']]['id'] = $value['id'];
$newArray[$value['uid']]['sum1'] += $value['sum1'];// Sum with previous value
$newArray[$value['uid']]['sum2'] += $value['sum2'];// Sum with previous value
}
}
$newArray = array_values($newArray);// Reset indexes, Start the array index with zero
print_r($newArray);// To see the output
Output:
Array
(
[0] => Array
(
[id] => 2
[uid] => 50
[sum1] => 3
[sum2] => 6
)
[1] => Array
(
[id] => 3
[uid] => 51
[sum1] => 3
[sum2] => 5
)
)
I think you are correct. Actually, i solved the problem using something similar:
$sumArray = Array();
foreach ($array1 as $item){
if(isset($sumArray[$item['uid']])){
$sumArray[$item['idPartener']]['sum1'] += $item['sum1'];
$sumArray[$item['idPartener']]['sum2'] += $item['sum2'];
}else{
$sumArray[$item['uid']] = Array(
'id' => $item['id'],
'sum1' => $item['sum1'],
'sum2' => $item['sum2'] ,
);
}
}
Thanks all for your help!

Removing first array of multidimensional array

I want to remove the first.. how to say that outside of the array and left inside array of a multidimension array. I couldn't found out the solution.. someone knows how to do it??
This is my code. I assign a array and i try to put into another array like this.
$final_sku = array();
foreach($skus as $sku){
foreach($sku as $key => $s){
$final_sku[] = array('Sku' => $s);
}
}
$newArray = array(
"Product" => array(
"PrimaryCategory" => "1",
"AssociatedSku" => "12",
"Attributes" => array(
),
"Skus" => $final_sku
)
);
And this is the $final_sku output be like.
[0] => Array
(
[Sku] => Array
(
[package_weight] => 5
[package_length] => 4
[package_width] => 3
[package_height] => 2
[package_content] =>
[tax_class] => default
[color_family] => Antique White
[price] => 4
[special_price] =>
[SellerSku] => sku1
[variation] => var1
)
)
[1] => Array
(
[Sku] => Array
(
[package_weight] => 5
[package_length] => 4
[package_width] => 3
[package_height] => 2
[package_content] =>
[tax_class] => default
[color_family] => Apricot
[price] => 4
[special_price] =>
[SellerSku] => sku2
[variation] => var1
)
)
I want the output be like this.
[Sku] => Array
(
[package_weight] => 5
[package_length] => 4
[package_width] => 3
[package_height] => 2
[package_content] =>
[tax_class] => default
[color_family] => Antique White
[price] => 4
[special_price] =>
[SellerSku] => sku1
[variation] => var1
)
[Sku] => Array
(
[package_weight] => 5
[package_length] => 4
[package_width] => 3
[package_height] => 2
[package_content] =>
[tax_class] => default
[color_family] => Apricot
[price] => 4
[special_price] =>
[SellerSku] => sku2
[variation] => var1
)
UPDATE: I want to pass the array and convert to xml. So the array key would be duplicated.
It does not make sense to have the same array of 2 members under the same key.
If you want to access one of them, what will be its uniqueness over the other?
The logical solution is
[sku] => [
0 => [first sku data....],
1 => [sku data....],
]

Filter multidimension array with conditional logic

I have below array,
Array ( [0] => Array ( [location] => X33 [usernumber] => 1 [order] => XX [part_number] => Hi ) [1] => Array ( [location] => X33 [usernumber] => 1 [order] => XX [part_number] => 68730 ) [2] => Array ( [location] => W33 [usernumber] => 2 [order] => YY [part_number] => 68741) [3] => Array ( [location] => W33 [usernumber] => 2 [order] => YY [part_number] => Hello )
I want to filter this array with usernumber = 1, by this it will create 1 array with arrays which have usernumber = 1, similarly it will create for usernumber=2
I had users in DB and will search user in this array,
I tried below code,
$users = $this->admin_model->get_usersforshipment();
foreach ($users as $user) {
$filtered = array_filter($csv_array, function($user)
{ //Below is retrurning as orignal $csv_array, not filtered,
return !empty($user['usernumber']);
});
}
Desired output, when $users['usernumber] == 1
Array ( [0] => Array ( [location] => X33 [usernumber] => 1 [order] => XX [part_number] => Hi ) [1] => Array ( [location] => X33 [usernumber] => 1 [order] => XX [part_number] => 68730 ) )
Desired output, when $users['usernumber] == 2
Array ( [0] => Array ( [location] => W33 [usernumber] => 2 [order] => YY [part_number] => 68741) [1] => Array ( [location] => W33 [usernumber] => 2 [order] => YY [part_number] => Hello )
How can i filter only 2 arrays from Multi Dimension array?
Online Example, Description added after your feedback.
$arr = array(
array ('location' => 'X33',
'usernumber' => 1,
'order' => 'XX',
'part_number' => 'Hi'
),
array ('location' => 'X33',
'usernumber' => 1,
'order' => 'XX',
'part_number' => '68730'
),
array ('location' => 'W33',
'usernumber' => 2,
'order' => 'YY',
'part_number' => '68741'
),
array ('location' => 'W33',
'usernumber' => 2,
'order' => 'YY',
'part_number' => 'Hello'
)
);
$out = array();
$index = $arr[0]['usernumber'];
foreach($arr as $val){
if($index != $val['usernumber'])
$index = $val['usernumber'];
$out[$index][] = $val;
}
echo '<pre>';
print_r($out);
Currently, your array is defined like so:
$array = [
0 => [
'location' => l1
'usernumber' => 1
'order' => 'o1'
],
1 => [
'location' => l2
'usernumber' => 1
'order' => 'o2'
],
2 => [
'location' => l3
'usernumber' => 2
'order' => 'o3'
]
];
A good solution would be to set the usernumber variables as array keys. You could do this while creating the array, or you could alter it after creation. It should look like this:
$array = [
1 => [ // The key is now the usernumber
[
'location' => 'l1'
'order' => 'o1'
],
[
'location' => 'l2'
'order' => 'o2'
]
],
2 => [
[
'location' => 'l3'
'order' => 'o3'
],
]
];
Now you can simple grab the different orders by the usernumber and loop through them:
$orders = $array[1]; // Get all orders from the user with usernumber 1
foreach ($orders as $order) {
print_r($order);
}

Create new array depending on key

My array is like that:
Array
(
[0] => Array
(
[des_id] => 1
[des_name] => bagan
[tran_id] => 1
[tran_name] => private
[tran_image] => 1251961905A1.jpg
[type] => car
[troute_id] => 10
)
[1] => Array
(
[des_id] => 1
[des_name] => bagan
[tran_id] => 2
[tran_name] => express
[tran_image] => bus3.jpg
[type] => car
[troute_id] => 13
)
[2] => Array
(
[des_id] => 1
[des_name] => bagan
[tran_id] => 3
[tran_name] => MyanmarTrain
[tran_image] => Burma-Gorteikviaduct.jpg
[type] => train
[troute_id] => 16
)
[3] => Array
(
[des_id] => 1
[des_name] => bagan
[tran_id] => 4
[tran_name] => Ayeyarwaddy Cruise
[tran_image] => boat-ChutzpahToo1.jpg
[type] => cruise
[troute_id] => 22
)
)
I want to change that array like that depending on key['type']. If array key['type'] are same, I want to change array like that:
Array
(
[car] => Array(
[0]=>Array
(
[des_id] => 1
[des_name] => bagan
[tran_id] => 1
[tran_name] => private
[tran_image] => 1251961905A1.jpg
[type] => car
[troute_id] => 10
),
[1] => Array
(
[des_id] => 1
[des_name] => bagan
[tran_id] => 2
[tran_name] => express
[tran_image] => bus3.jpg
[type] => car
[troute_id] => 13
)
),
[train]=>Array(
[0] => Array
(
[des_id] => 1
[des_name] => bagan
[tran_id] => 3
[tran_name] => MyanmarTrain
[tran_image] => Burma-Gorteikviaduct.jpg
[type] => train
[troute_id] => 16
)
[cruise]=>Array(
[0] => Array
(
[des_id] => 1
[des_name] => bagan
[tran_id] => 4
[tran_name] => Ayeyarwaddy Cruise
[tran_image] => boat-ChutzpahToo1.jpg
[type] => cruise
[troute_id] => 22
)
)
)
)
what I mean is that if key['type'] is car, I want to create car array or if the type is train I want to create train array or if the type is cruise I want to create cruise array. I don't know how to loop the array. Anyone please help me. Thanks a lot!
Here's a simple way to do it: loop over the data, and just append to the subarray matching the type value:
// starting data
$starting_array = array (
0 => array (
'des_id' => 1,
'des_name' => 'bagan',
'tran_id' => 1,
'tran_name' => 'private',
'tran_image' => '1251961905A1.jpg',
'type' => 'car',
'troute_id' => 10
),
1 => array (
'des_id' => 1,
'des_name' => 'bagan',
'tran_id' => 2,
'tran_name' => 'express',
'tran_image' => 'bus3.jpg',
'type' => 'car',
'troute_id' => 13
),
2 => array (
'des_id' => 1,
'des_name' => 'bagan',
'tran_id' => 3,
'tran_name' => 'MyanmarTrain',
'tran_image' => 'Burma-Gorteikviaduct.jpg',
'type' => 'train',
'troute_id' => 16
),
3 => array (
'des_id' => 1,
'des_name' => 'bagan',
'tran_id' => 4,
'tran_name' => 'Ayeyarwaddy Cruise',
'tran_image' => 'boat-ChutzpahToo1.jpg',
'type' => 'cruise',
'troute_id' => 22
)
);
// initialize the result array
$result = array();
// loop over the starting array
foreach($starting_array as $entry) {
// make sure the result array has a key matching this item's type
if(!array_key_exists($entry['type'], $result)) {
$result[ $entry['type'] ] = array();
}
// add this item to the result array
$result[ $entry['type'] ][] = $entry;
}
// this is just for testing, so you can verify the output matches your desired result
echo "<pre>";
var_dump($result);
echo "</pre>";
Try this:
<?php
$tempArr = Array
(
Array(
"des_id" => 1,
"des_name" => "bagan",
"tran_id" => 1,
"tran_name" => "private",
"tran_image" => "1251961905A1.jpg",
"type" => "car",
"troute_id" => 10
),
Array
(
"des_id" => 1,
"des_name" => "bagan",
"tran_id" => 2,
"tran_name" => "express",
"tran_image" => "bus3.jpg",
"type" => "car",
"troute_id" => 13
),
Array
(
"des_id" => 1,
"des_name" => "bagan",
"tran_id" => 3,
"tran_name" => "MyanmarTrain",
"tran_image" => "Burma-Gorteikviaduct.jpg",
"type" => "train",
"troute_id" => 16
),
Array
(
"des_id" => 1,
"des_name" => "bagan",
"tran_id" => 4,
"tran_name" => "Ayeyarwaddy Cruise",
"tran_image" => "boat-ChutzpahToo1.jpg",
"type" => "cruise",
"troute_id" => 22
)
);
$resultArr = array();
foreach($tempArr as $tempKey=>$temp)
{
if(!array_key_exists($temp['type'], $resultArr))
{
$resultArr[$temp['type']] = array();
}
$resultArr[$temp['type']][] = $temp;
}
echo '<pre>';
print_r($resultArr);
?>
This is working fine .....

Categories