Sum values from a multidimensional array in PHP - php

Supposing I have this array in PHP:
Array
(
[0] => Array
(
[name] => Banana
[quantity] => 124
)
[1] => Array
(
[name] => Cherry
[quantity] => 24
)
[2] => Array
(
[name] => Apple
[quantity] => 224
)
)
How can I sum the number with the key quantity ?
Thanks.

Please, always share with us what you have tried.
It help us a lot.
You can use:
$arr = [['name' => "Banana", 'quantity' => 124], ['name' => "Cherry", 'quantity' => 24], ['name' => "Apple", 'quantity' => 224]];
$sum = 0;
foreach ($arr as $item) {
$sum += $item['quantity'];
}
Or (PHP 5.5+):
$sum = array_sum(array_column($arr, 'quantity'));

/*
Receives a Multidemensional Array (Matrix) and returns the sum of quantity.
Returns -1 on fail.
*/
function SumKeyOfArray($Matrix)
{
if(!empty($Matrix))
{
$sum = 0;
foreach($Matrix as $array)
{
if(isset($array['quantity']))
$sum = $sum + $array['quantity'];
}
return $sum;
}
return -1;
}

Another option is to use the reduce function:
$arr= [['name' => "Banana", 'quantity' => 124], ['name' => "Cherry", 'quantity' => 24], ['name' => "Apple", 'quantity' => 224]];
echo array_reduce($arr, function($sum, $elem) {
return $sum += $elem["quantity"];
});

Related

how to explode array in php

i have data array, and this my array
Array
(
[0] => Array
(
[id] => 9,5
[item] => Item A, Item B
)
[1] => Array
(
[id] => 3
[item] => Item C
)
)
in array 0 there are two ID which I separated using a comma, I want to extract the data into a new array, how to solve this?
so the output is like this
Array
(
[0] => Array
(
[id] => 9
[item] => Item A
)
[1] => Array
(
[id] => 3
[item] => Item C
)
[2] => Array //new array
(
[id] => 5
[item] => Item B
)
)
this my code
$arr=array();
foreach($myarray as $val){
$arr[] = array(
'id' => $val['id'],
'item' => $val['item'],
);
}
echo '<pre>', print_r($arr);
$arr = [
array(
'id' => '9,5',
'item' => 'Item A, Item B'
),
array(
'id' => 3,
'item' => 'Item C'
)
];
$newArr = array_reduce($arr, function($tmp, $ele){
$arrIds = explode(',', $ele['id']);
$arrItems = explode(',', $ele['item']);
forEach($arrIds as $key => $arrId) {
$tmp[] = array('id' => $arrId, 'item' => $arrItems[$key]);
}
return $tmp;
});
The code down below should do the job. But I didn't understand why you didn't create those items seperately in the first place.
foreach ($arr as $i => $data) {
if (!str_contains($data['id'], ',')) continue;
$items = explode(',', $data['item']);
foreach(explode(',', $data['id']) as $i => $id) {
$new = ['id' => $ids[$i], 'item' => $items[$i]];
if ($i) $arr[] = $new;
else $arr[$i] = $new;
}
}

How to combine the same values in an array in foreach loop in php

i want to combine the values of array having same index name in foreach loop..
i tried array_combine but it returns the single array.
$data = $_POST['variable']; //it contain the values in an array
$result=array();
foreach ($data as $mycat){
$result = array_merge($result, $mycat);
}
echo "<pre>";print_r($result);echo "</pre>";
it returns only data in single array
Array
(
[vendor] => 1-Open Market
[priority] => 2
[demand_for_id] => 9
[ims_allocation_details_id] => 148
[temp_demand_id] => 1
)
as shown in attached picture item names are same, so when item names are same i want to combine the total values in foreach and insert only one record into database instead to two
enter image description here
the contents of $_POST['variable']; are
Array
(
[2] => Array
(
[vendor] => 1-Open Market
[temp_demand_id] => 6
[priority] => 1
[item_name] => BAJRA MOTI
[amount] => 1000
[demand_for_id] => 9
[ims_allocation_details_id] => 153
)
[1] => Array
(
[vendor] => 1-Open Market
[temp_demand_id] => 1
[priority] => 2
[item_name] => BAJRA MOTI
[amount] => 2500
[demand_for_id] => 9
[ims_allocation_details_id] => 148
)
)
You should replace
$result = array_merge($result, $mycat);
with
$result[] = array_merge($result, $mycat);
and it will not be single
UPDATE
$result = array();
foreach ($data as $mycat) {
if(!isset($result[$mycat['item_name']])) {
$result[$mycat['item_name']] = $mycat;
} else {
//do if needed
}
}
echo "<pre>";print_r($result);echo "</pre>";
You can create a custom function to solve your problem.
Example:
<?php
$array = [
[
'vendor' => '1-Open Market',
'temp_demand_id' => 6,
'priority' => 1,
'item_name' => 'BAJRA MOTI',
'amount' => 1000,
'demand_for_id' => 9,
'ims_allocation_details_id' => 153,
],
[
'vendor' => '1-Open Market',
'temp_demand_id' => 1,
'priority' => 2,
'item_name' => 'BAJRA MOTI',
'amount' => 2500,
'demand_for_id' => 9,
'ims_allocation_details_id' => 148,
],
[
'vendor' => '1-Open Market',
'temp_demand_id' => 5,
'priority' => 3,
'item_name' => 'BAJRA MOTI',
'amount' => 1000,
'demand_for_id' => 11,
'ims_allocation_details_id' => 200,
],
];
function array_merge_recursive_custom($array) {
$processed = null;
foreach ($array as &$subArray) {
if (empty($processed)) {
$processed = $subArray;
continue;
}
foreach ($subArray as $key => $value) {
if (is_numeric($value)) {
$subArray[$key] += $processed[$key];
}
}
$processed = $subArray;
}
return end($array);
}
var_dump(array_merge_recursive_custom($array));

Add Sum from JSON

I'm fairly new with PHP and I need help with adding certain row from JSON file.
For instance i have
Array
(
[0] => Array
(
[id] => 1
[name] => "Computer"
[price] => 1000
)
[1] => Array
(
[id] => 1
[name] => "Mouse"
[price] => 14
)
[2] => Array
(
[id] => 1
[name] => "Computer"
[price] => 1500
)
[3] => Array
(
[id] => 1
[name] => "Mouse"
[price] => 16
)
)
the output should be
Array(
[name] => "Computer"
[sum] => 2500
)
Array(
[name] => "Mouse"
[sum] => 30
)
I tried using this
$i = 0;
foreach ($array as $rows){
$i += $rows['price'];
}
but this one basically adds them all.
I appreciate the help!
Code
<?php
// make origin
$array_origin = array(
array('id' => 1,'name' => 'Computer','price' => 1000),
array('id' => 1,'name' => 'Mouse','price' => 14),
array('id' => 1,'name' => 'Computer','price' => 1500),
array('id' => 1,'name' => 'Mouse','price' => 16),
);
echo '<pre>' . var_export($array_origin, true) . '</pre><hr>';
// store name-price pair
$stack=array();
foreach ($array_origin as $index => $array_part) {
$stack[$array_part['name']]=array_key_exists($array_part['name'],$stack)?$stack[$array_part['name']]+$array_part['price']:$array_part['price'];
}
// make output
$j=0;
$output=array();
foreach ($stack as $name => $sum) {
$output[]=array(
'name' => $name,
'sum' => $sum
);
echo '<pre>' . var_export($output[$j], true) . '</pre>';
$j++;
}
Output
Or use json to make origin array
$json_str='[
{
"id":1,
"name":"Computer",
"price":"1000"
},
{
"id":1,
"name":"Mouse",
"price":14
},
{
"id":1,
"name":"Computer",
"price":1500
},
{
"id":1,
"name":"Mouse",
"price":16
}
]';
$array_origin=json_decode($json_str, true);
Hope it can help you ~
since you wrote all that out, I guess I can write you a quick loop.
$answer = array();
foreach($oldarray as $val)
{
#$answer[$val['name']] += $val['sum'];
}
print_r($answer);
It's not the exact answer, but it will get you there.
Try this code:
$result = [];
foreach ($array as $row) {
if (array_key_exists($row['name'], $result)) {
$result[$row['name']]['sum'] += $row['price'];
} else {
$result[$row['name']] = [
'name' => $row['name'],
'sum' => $row['price'],
];
}
}
print_r($result);

PHP merge arrays by value for 2 different array value

I have tried to merge two different arrays into a single array. Can any one help me please?
i have array like this
[0] (Array)#2
[rank] "579"
[id] "1"
[1] (Array)#4
[rank] "251"
[id] "2"
[0] (Array)#2
[size] "S"
[rank] "251"
[1] (Array)#15
[size] "L"
[rank] "579"
i need like this
[0] (Array)#2
[size] "S"
[rank] "251"
[id] "1"
[1] (Array)#15
[size] "L"
[rank] "579"
[id] "1"
Untested, but this should work, or at least get you close.
for ($array1 as $key1 => $value1) {
for ($array2 as $key2 => $value2) {
if ($value1['rank'] == $value2['rank']) {
$result[$key1] = [$value2['size'], $value1['rank'], $value1['id']];
};
};
};
foreach($arr1 as $key1 => $data1){
foreach($arr2 as $key2 => $data2){
if($data1['rank']==$data2['rank']){
$result[] = array_merge($data1, $data2);
}
}
}
print_r($result);
//save keys of ranks in the 1st array
$keys = array();
foreach($arr1 as $k => $v)
$keys[$v['rank']] = $k;
$res = array();
// Walk through the 2nd array and make result
foreach($arr2 as $k => $v)
if (isset($keys[$v['rank']]))
$res[] = array_merge($arr1[$keys[$v['rank']]], $v);
print_r($res);
Looking at your provided arrays, I'm assuming you want to use the key rank as the joining point (which doesn't seems such a good idea, and question will be if their unique or not) if they are unique then a tiny method can help to fetch element based on their rank and the rest is just assembling the result :
<?php
$arr1 = [
[
'rank' => 579,
'id' => 1
],
[
'rank' => 251,
'id' => 2
],
];
$arr2 = [
[
'size' => 'S',
'rank' => 251
],
[
'size' => 'L',
'rank' => 579
],
];
function getItemByRank($array, $rank)
{
foreach ($array as $item){
if ($item['rank'] === $rank) {
return $item;
}
}
}
$result = [];
foreach ($arr1 as $k => $item) {
$match = getItemByRank($arr2, $item['rank']);
if (isset($match)) {
$result[$k] = $item;
$result[$k]['size'] = $match['size'];
}
}
print_r($result);
output:
Array
(
[0] => Array
(
[rank] => 579
[id] => 1
[size] => L
)
[1] => Array
(
[rank] => 251
[id] => 2
[size] => S
)
)
While I do not understand why you want to merge the arrays this way, here's a way to merge the arrays by their sequences. so the first child of array1 will be merged with the first child of array2 etc.
<?php
$array1 = [
[
'rank' => 579,
'id' => 1
],
[
'rank' => 251,
'id' => 2
]
];
$array2 = [
[
'size' => 'S',
'rank' => 251
],
[
'size' => 'L',
'rank' => 579
]
];
foreach ($array1 as $key => &$data) {
if (isset($array2[$key])) {
$data = array_merge($data, $array2[$key]);
}
}
var_dump($array1);

Group array rows by one column and only create a subarray from another column if more than one value

How can I group row data from a two-dimensional array and only create a subarray of another column if the respective group contains more than one value?
In other words, I need to group rows by id and conditionally restructure an array of arrays to have a variable depth of either 2 or 3 levels.
Input:
[
['id' => 567, 'value' => 780],
['id' => 676, 'value' => 743],
['id' => 676, 'value' => 721],
['id' => 234, 'value' => 766],
['id' => 234, 'value' => 680]
]
Desired output:
[
['id' => 567, 'value' => 780],
['id' => 676, 'value' => [743, 721]],
['id' => 234, 'value' => [766, 680]]
]
Are you sure you want to have the value as an integer when there is one value and an array when there are more?
<?php
$array = array(
array('id' => 567, 'value' => 780),
array('id' => 676, 'value' => 743),
array('id' => 676, 'value' => 721),
array('id' => 234, 'value' => 766),
array('id' => 234, 'value' => 680)
);
foreach ($array as $item) {
$result[$item['id']][] = $item['value'];
}
foreach ($result as $id => $value) {
if (count($value) > 1) {
$output[] = array(
'id' => $id,
'value' => $value
);
} else {
$output[] = array(
'id' => $id,
'value' => $value[0]
);
}
}
echo '<pre>';
print_r($output);
echo '</pre>';
?>
If not
<?php
$array = array(
array('id' => 567, 'value' => 780),
array('id' => 676, 'value' => 743),
array('id' => 676, 'value' => 721),
array('id' => 234, 'value' => 766),
array('id' => 234, 'value' => 680)
);
foreach ($array as $item) {
$result[$item['id']][] = $item['value'];
}
foreach ($result as $id => $value) {
$output[] = array(
'id' => $id,
'value' => $value
);
}
echo '<pre>';
print_r($output);
echo '</pre>';
?>
try this one
$array['key1'] = array(
0=>array('id'=>567, 'value'=>780),
1=>array('id'=>676, 'value'=>743),
2=>array('id'=>676, 'value'=>721),
3=>array('id'=>234, 'value'=>766),
4=>array('id'=>234, 'value'=>780)
);
foreach($array['key1'] as $subarray){
$group_id = $subarray['id'];
if(!isset($return[$group_id]))
$return[$group_id] = $subarray;
else{
if(is_array($return[$group_id]['value']))
array_push($return[$group_id]['value'], $subarray['value']);
else
$return[$group_id]['value'] = array($subarray['value'], $return[$group_id]['value']);
}
}
// reset grouping keys into 0,1...
$return = array_values($return);
print_r($return);
There, all the work done for you. How easy is that!
//create the array as you have now
$array[0] = ['id'=>567, 'value'=>780];
$array[1] = ['id'=>676, 'value'=>743];
$array[2] = ['id'=>676, 'value'=>721];
$array[3] = ['id'=>234, 'value'=>766];
$array[4] = ['id'=>234, 'value'=>780];
print_r($array);
print chr(10).chr(10);
//create a new array with the values combined on key
$concat = array();
foreach($array as $val) {
$i = $val['id'];
$v = $val['value'];
if (!is_array($concat[$i]))
$concat[$i] = array();
$concat[$i][] = $v;
}
print_r($concat);
print chr(10).chr(10);
//create a new array to show the data as you want.
$newarray = array();
foreach($concat as $key=>$val) {
$t = array();
$t['id'] = $key;
if (count($val)==1)
$t['value'] = $val[0];
else {
$t['value'] = array();
foreach($val as $v)
$t['value'][] = $v;
}
$newarray[] = $t;
}
print_r($newarray);
print chr(10).chr(10);
Result:
Array
(
[0] => Array
(
[id] => 567
[value] => 780
)
[1] => Array
(
[id] => 676
[value] => 743
)
[2] => Array
(
[id] => 676
[value] => 721
)
[3] => Array
(
[id] => 234
[value] => 766
)
[4] => Array
(
[id] => 234
[value] => 780
)
)
Array
(
[567] => Array
(
[0] => 780
)
[676] => Array
(
[0] => 743
[1] => 721
)
[234] => Array
(
[0] => 766
[1] => 780
)
)
Array
(
[0] => Array
(
[id] => 567
[value] => 780
)
[1] => Array
(
[id] => 676
[value] => Array
(
[0] => 743
[1] => 721
)
)
[2] => Array
(
[id] => 234
[value] => Array
(
[0] => 766
[1] => 780
)
)
)
<?php
$arr['key1'] = array(
array(
'id' => 567,
'value' => 780,
),
array(
'id' => 676,
'value' => 743,
),
array(
'id' => 676,
'value' => 721,
),
array(
'id' => 234,
'value' => 766,
),
array(
'id' => 234,
'value' => 780,
),
);
/* handle element merge */
function array_internal_merge_func($a, $b) {
if ( is_array($a['value']) )
$a['value'][] = $b['value'];
else
$a['value'] = array($a['value'], $b['value']);
return $a;
}
/* handle array merge */
function array_internal_merge($array, $key, $merge_func) {
$hashed = array();
$result = array();
foreach ( $array as $idx => $ele )
$hashed[$ele[$key]][] = $idx;
foreach ( $hashed as $key => $idxies ) {
reset($idxies);
$idx0 = current($idxies);
$result[$idx0] = $array[$idx0];
while ( $idx = next($idxies) )
$result[$idx0] = $merge_func($result[$idx0], $array[$idx]);
}
return $result;
}
print_r(array_internal_merge($arr['key1'], 'id', 'array_internal_merge_func'));
This task can certainly be done concisely with one loop.
Use id column values as temporary first level keys. This makes identifying duplicates most efficient and easy.
While iterating:
if a row's id is new to the result array, then push the whole row (in its original, flat structure) into the result array; or
if a row's id was encountered before, then cast the stored row's value element as an array before pushing the current row's value into that subarray.
If you do not want your result to have id values as the first level keys, then call array_values() to re-index the result.
The special action done implemented below is that when casting a scalar or null data type to an array, the value becomes the lone element of the newly formed array. If an array is explicitly cast as an array, then there is no effect on the data structure at all. This is why (array) can be unconditionally applied in the else branch.
Code: (Demo)
foreach ($array as $row) {
if (!isset($result[$row['id']])) {
$result[$row['id']] = $row;
} else {
$result[$row['id']]['value'] = array_merge(
(array) $result[$row['id']]['value'],
[$row['value']]
);
}
}
var_export(array_values($result));
An alternative without array_merge(): (Demo)
foreach ($array as $row) {
if (!isset($result[$row['id']])) {
$result[$row['id']] = $row;
} else {
$result[$row['id']]['value'] = (array) $result[$row['id']]['value'];
$result[$row['id']]['value'][] = $row['value'];
}
}
var_export(array_values($result));
An alternative with array_reduce(): (Demo)
var_export(
array_values(
array_reduce(
$array,
function($result, $row) {
if (!isset($result[$row['id']])) {
$result[$row['id']] = $row;
} else {
$result[$row['id']]['value'] = (array) $result[$row['id']]['value'];
$result[$row['id']]['value'][] = $row['value'];
}
return $result;
}
)
)
);

Categories