php function to sum values from multi dimensional array - php

My $results array looks like this..
$results = [
'2020-09-06' => [
'Etsy' => ['total_orders' => 2, 'total_stickers' => 3, 'total_value' => 7.8300000000000001],
'Woo' => ['total_orders' => 10, 'total_stickers' => 20, 'total_value' => 100.38],
'eBay' => ['total_orders' => 17, 'total_stickers' => 18, 'total_value' => 67.359999999999999],
],
'2020-09-07' => [
'Etsy' => ['total_stickers' => 8, 'total_orders' => 4, 'total_value' => 34.920000000000002],
'Woo' => ['total_stickers' => 9, 'total_orders' => 3, 'total_value' => '52.90'],
'eBay' => ['total_stickers' => 23, 'total_orders' => 21, 'total_value' => 58.030000000000001],
]
];
I want to echo the combined sum for each individual item (total_value, total_stickers, total_orders) for each "marketplace" by date and thought i could do this if i pass the variables in a function and tried the following..
$array_value_sum = create_function('$array,$key', '$total = 0; foreach($array as $row) $total = $total + $row[$key]; return $total;');
echo "Total Current Value" . $array_value_sum($obj['results'], 'total_value');
That way I can change the variables and sum any of them with a similar echo line but this is not working for me, do I also need to specify dates in a foreach? or how can I achieve this expected output..
Array
(
[2020-09-06] => Array
(
[total_orders] => 29
[total_stickers] => 41
[total_value] => 175.5
)
[2020-09-07] => Array
(
[total_stickers] => 40
[total_orders] => 28
[total_value] => 145.85
)
)

As always, no need to over-engineer, if you know the structure, just iterate trough the values, and sum them up, this is how I would do that.
This way you can add many other marketplace and dates without later modifying the code.
<?php
$results = [
'2020-09-06' => [
'Etsy' => ['total_orders' => 2, 'total_stickers' => 3, 'total_value' => 7.8300000000000001],
'Woo' => ['total_orders' => 10, 'total_stickers' => 20, 'total_value' => 100.38],
'eBay' => ['total_orders' => 17, 'total_stickers' => 18, 'total_value' => 67.359999999999999],
],
'2020-09-07' => [
'Etsy' => ['total_stickers' => 8, 'total_orders' => 4, 'total_value' => 34.920000000000002],
'Woo' => ['total_stickers' => 9, 'total_orders' => 3, 'total_value' => '52.90'],
'eBay' => ['total_stickers' => 23, 'total_orders' => 21, 'total_value' => 58.030000000000001],
]
];
$total = ['total_stickers' => 0, 'total_orders' => 0, 'total_value' => 0];
foreach ($results as $k => $v){
foreach ($v as $k1 => $v1){
$total['total_stickers'] += $v1['total_stickers'];
$total['total_orders'] += $v1['total_orders'];
$total['total_value'] += $v1['total_value'];
}
}
var_dump($total);
/*
* array(3) {
["total_stickers"]=>
int(81)
["total_orders"]=>
int(57)
["total_value"]=>
float(321.42)
}
* */

One way would be to simply loop over it with a couple of foreach's and add the values together.
Sum all by date, including all marketplaces.
<?php
$result = [];
foreach ($data as $date => $marketplaces) {
foreach ($marketplaces as $data) {
if (!isset($result[$date])) $result[$date] = ['total_orders' => 0, 'total_stickers' => 0, 'total_value' => 0];
$result[$date] = [
'total_stickers' => $result[$date]['total_stickers'] + $data['total_stickers'],
'total_orders' => $result[$date]['total_orders'] + $data['total_orders'],
'total_value' => $result[$date]['total_value'] + $data['total_value'],
];
}
}
print_r($result);
Result:
Array
(
[2020-09-06] => Array
(
[total_stickers] => 41
[total_orders] => 29
[total_value] => 175.57
)
[2020-09-07] => Array
(
[total_stickers] => 40
[total_orders] => 28
[total_value] => 145.85
)
)
https://3v4l.org/qQ04D
Original answer: Sum all marketplaces.
<?php
$result = [];
foreach ($data as $date => $marketplaces) {
foreach ($marketplaces as $marketplace => $data) {
if (!isset($result[$marketplace])) {
$result[$marketplace] = $data;
} else {
$result[$marketplace] = [
'total_stickers' => $result[$marketplace]['total_stickers'] + $data['total_stickers'],
'total_orders' => $result[$marketplace]['total_orders'] + $data['total_orders'],
'total_value' => $result[$marketplace]['total_value'] + $data['total_value'],
];
}
}
}
print_r($result);
Result:
Array
(
[Etsy] => Array
(
[total_stickers] => 11
[total_orders] => 6
[total_value] => 42.75
)
[Woo] => Array
(
[total_stickers] => 29
[total_orders] => 13
[total_value] => 153.28
)
[eBay] => Array
(
[total_stickers] => 41
[total_orders] => 38
[total_value] => 125.39
)
)
https://3v4l.org/g4CmZ

Related

multidimensional array php - sum values with same groupRange

I will try to explain my problem in small examples:
I have a multidimensional array that represents data from the database, lets's say the input looks like this:
Array
(
[0] => Array
(
[groupRange] => 20-25
[value] => 12
[followersFemaleRate] => 12
[followersMaleRate] => 14
)
[1] => Array
(
[groupRange] => 30-44
[value] => 32
[followersFemaleRate] => 17
[followersMaleRate] => 3
)
[2] => Array
(
[groupRange] => 30-44
[value] => 88
[followersFemaleRate] => 17
[followersMaleRate] => 3
)
)
What I want? To sum value, followersFemaleRate, followersMaleRate with the same groupRange, so the output should be this:
Array
(
[0] => Array
(
[groupRange] => 20-25
[value] => 12
[followersFemaleRate] => 12
[followersMaleRate] => 14
)
[1] => Array
(
[groupRange] => 30-44
[value] => 120
[followersFemaleRate] => 34
[followersMaleRate] => 6
)
)
My code:
$RangeArray = [];
foreach($dbProfile->getData() as $d) {
foreach ($d->getGroupPercentages() as $x){
$ageRangeSingleArray['groupRange'] = $x->getGroupRange();
$ageRangeSingleArray['value'] = $x->getValue();
$ageRangeSingleArray['followersFemaleRate'] = $x->getFollowerGenderFemale();
$ageRangeSingleArray['followersMaleRate'] = $x->getFollowerGenderMale();
$RangeArray [] = $ageRangeSingleArray;
}
}
However im stuck, my idea is to first check if groupRage already exists, if yes, sum values for that range, if not add new element groupRange with values, any help with code?
#Salines solution was good, but I offer a simple solution for the beginners...
Another simple solution to your problem:
$input = [
[
'groupRange' => '20-25',
'value' => 12,
'followersFemaleRate' => 12,
'followersMaleRate' => 14,
],
[
'groupRange' => '30-44',
'value' => 88,
'followersFemaleRate' => 17,
'followersMaleRate' => 3,
],
[
'groupRange' => '30-44',
'value' => 32,
'followersFemaleRate' => 17,
'followersMaleRate' => 3,
],
];
$groupRangeHolder = [];
$output = [];
foreach($input as $item) {
if( ! array_key_exists( $item['groupRange'] , $groupRangeHolder ) )
{
$groupRangeHolder[$item['groupRange']]['value'] = $item['value'];
$groupRangeHolder[$item['groupRange']]['followersFemaleRate'] = $item['followersFemaleRate'];
$groupRangeHolder[$item['groupRange']]['followersMaleRate'] = $item['followersMaleRate'];
}
else
{
$groupRangeHolder[$item['groupRange']]['value'] += $item['value'];
$groupRangeHolder[$item['groupRange']]['followersFemaleRate'] += $item['followersFemaleRate'];
$groupRangeHolder[$item['groupRange']]['followersMaleRate'] += $item['followersMaleRate'];
}
}
$cur = 0;
foreach($groupRangeHolder as $key => $values)
{
$output[$cur]['groupRange'] = $key;
$output[$cur]['value'] = $values['value'];
$output[$cur]['followersFemaleRate'] = $values['followersFemaleRate'];
$output[$cur++]['followersMaleRate'] = $values['followersMaleRate'];
}
echo "<pre>";
print_r($output);
echo "</pre>";
try:
$input = [
[
'groupRange' => '20-25',
'value' => 12,
'followersFemaleRate' => 12,
'followersMaleRate' => 14,
],
[
'groupRange' => '30-44',
'value' => 88,
'followersFemaleRate' => 17,
'followersMaleRate' => 3,
],
[
'groupRange' => '30-44',
'value' => 32,
'followersFemaleRate' => 17,
'followersMaleRate' => 3,
],
];
$groupedArray = [];
foreach( $input as $item ){
$groupedArray[$item['groupRange']]['groupRange'] = $item['groupRange'];
$groupedArray[$item['groupRange']]['value'] = ($groupedArray[$item['groupRange']]['value'] ?? 0) + $item['value'];
$groupedArray[$item['groupRange']]['followersFemaleRate'] = $item['followersFemaleRate'];
$groupedArray[$item['groupRange']]['followersMaleRate'] = $item['followersMaleRate'];
}
$output = array_values($groupedArray);
print_r($output);
output:
Array
(
[0] => Array
(
[groupRange] => 20-25
[value] => 12
[followersFemaleRate] => 12
[followersMaleRate] => 14
)
[1] => Array
(
[groupRange] => 30-44
[value] => 120
[followersFemaleRate] => 17
[followersMaleRate] => 3
)
)

How to delete an array list based on key?

For instance :
Array
(
[0] => Array
(
[id] => 23
[merchant_id] => 23
)
[1] => Array
(
[id] => 24
[merchant_id] => 46
)
)
I want to delete the list which merchant_id except 46, after the operation:
Array
(
[0] => Array
(
[id] => 24
[merchant_id] => 46
)
)
how the best way to removing this array list?
You can get result using array_filter as follows
// suppose your data is in $data variable
$data = [
['id' => 23,
'merchant_id' => 23],
['id' => 23,
'merchant_id' => 46],
];
//return true only if marchant_id == 46
$filtered_array = array_filter($data,function($datum){
return $datum["merchant_id"] == 46;
});
Hi Please check below code
$array = array(
array('id' => 23, 'merchant_id' => 23),
array('id' => 24, 'merchant_id' => 46),
array('id' => 25, 'merchant_id' => 34),
array('id' => 26, 'merchant_id' => 46),
);
$final = array();
foreach ($array as $key => $value) {
if($value['merchant_id'] == 46){
$final[] = $value;
}
}
print_r($final);
If you are struggling with the array functions a simple foreach loop and a test of the field you are interested in would do nicely
$A = [ ['id' => 23, 'merchant_id' => 23 ],
['id' => 24, 'merchant_id' => 46 ],
['id' => 25, 'merchant_id' => 21 ],
['id' => 26, 'merchant_id' => 29 ],
];
foreach ( $A as $key => $t ) {
if( $t['merchant_id'] != 46 ){
unset($A[$key]);
}
}
print_r($A);
RESULT
Array
(
[1] => Array
(
[id] => 24
[merchant_id] => 46
)
)

how to sum 2 specific field of array if id was same in php

Guys I want to sum two array fields liked_cnt , coupon_cnt if first field id is same
how can I do this?
I did this but its toooooo slow
if (end($like)['id'] > end($coupon)['id']) {
$i = end($like)['id'];
$j = end($coupon)['id'];
}else {
$i = end($coupon)['id'];
$j = end($like)['id'];
}
for ($k=0; $k <= $i; $k++) {
for ($l=0; $l < $j; $l++) {
if ($like['id'] == $coupon['id']) {
$score[$like['id']] = ($coupon['coupon_cnt'] * 1000) + $like['liked_cnt'];
}else {
$score[$i] = 0;
}
}
}
//first array $Like
Array ( [0] => Array ( [id] => 85 [liked_cnt] => 6 ) [1] => Array ( [id] => 86 [liked_cnt] => 14 ) [2] => Array ( [id] => 92 [liked_cnt] => 6 ) [3] => Array ( [id] => 93 [liked_cnt] => 6 )
//second array $coupon
Array ( [0] => Array ( [id] => 35 [coupon_cnt] => 2 ) [1] => Array ( [id] => 86 [coupon_cnt] => 1 ) [2] => Array ( [id] => 139 [coupon_cnt] => 1 ) )
There is no magic algorithm builtin to php that can really compute your desired result in a much more efficient way. This might be slightly more efficient, but most of all it is more readable:
<?php
$input = [
[
['id' => 85, 'liked_cnt' => 6],
['id' => 86, 'liked_cnt' => 14],
['id' => 92, 'liked_cnt' => 6],
['id' => 93, 'liked_cnt' => 6]
],
[
['id' => 35, 'coupon_cnt' => 2],
['id' => 86, 'coupon_cnt' => 1],
['id' => 139, 'coupon_cnt' => 1]
]
];
$output = [];
foreach ($input as $set) {
array_walk($set, function($entry) use (&$output) {
$count = array_pop($entry);
$id = array_pop($entry);
if (array_key_exists($id, $output)) {
$output[$id]['total_cnt'] += $count;
} else {
$output[$id] = ['id' => $id, 'total_cnt' => $count];
}
});
}
print_r(array_values($output));
The output obviously is:
Array
(
[0] => Array
(
[id] => 85
[total_cnt] => 6
)
[1] => Array
(
[id] => 86
[total_cnt] => 15
)
[2] => Array
(
[id] => 92
[total_cnt] => 6
)
[3] => Array
(
[id] => 93
[total_cnt] => 6
)
[4] => Array
(
[id] => 35
[total_cnt] => 2
)
[5] => Array
(
[id] => 139
[total_cnt] => 1
)
)
UPDATE:
Considering your third comment below I add this modified version introducing the general multiplication of the coupon_cnt attribute by a factor 1000:
<?php
$input = [
[
['id' => 85, 'liked_cnt' => 6],
['id' => 86, 'liked_cnt' => 14],
['id' => 92, 'liked_cnt' => 6],
['id' => 93, 'liked_cnt' => 6]
],
[
['id' => 35, 'coupon_cnt' => 2],
['id' => 86, 'coupon_cnt' => 1],
['id' => 139, 'coupon_cnt' => 1],
['id' => 99, 'coupon_cnt' => 99]
]
];
$output = [];
foreach ($input as $set) {
array_walk($set, function($entry) use (&$output) {
$count = array_key_exists('coupon_cnt', $entry)
? 1000 * array_pop($entry)
: array_pop($entry);
$id = array_pop($entry);
if (array_key_exists($id, $output)) {
$output[$id]['total_cnt'] += $count;
} else {
$output[$id] = ['id' => $id, 'total_cnt' => $count];
}
});
}
print_r(array_values($output));

Extract a row by value from php array

This is my array:
Array (
[0] => Array ( [SocketID] => 1 [SocketName] => Name [SocketDecimal] => 0 [SocketHex] => 00 [SocketAtt] => 1 [Category] => 1 [Value] => 100 [Procentage] => 0 )
[1] => Array ( [SocketID] => 2 [SocketName] => Name2 [SocketDecimal] => 50 [SocketHex] => 32 [SocketAtt] => 1 [Category] => 1 [Value] => 800 [Procentage] => 0 )
[2] => Array ( [SocketID] => 3 [SocketName] => Name3 [SocketDecimal] => 100 [SocketHex] => 64 [SocketAtt] => 1 [Category] => 1 [Value] => 60 [Procentage] => 0 )
)
How can I extract a row by SocketDecimal?
For example: I want to extract row where SocketDecimal = 50 and make new an array only with that row.
foreach($array as $entry) {
if($entry['SocketDecimal'] == 50)
$newArr[] = $entry;
}
$newArr will contain the desired "row". Of course you can manipulate the if-statement depending on which "row" (I'd just call it array entry) you want to extract.
It's not the best way for big data! It's easy for deep multiarrays.
$arr = array(
array('socket_id'=>1,'name'=>'test1'),
array('socket_id'=>2,'name'=>'test2'),
array('socket_id'=>3,'name'=>'test3'),
array('socket_id'=>2,'name'=>'test4')
);
$newArr = array();
foreach($arr as $row){
foreach($row as $key=>$r){
if($key == 'socket_id' && $r==2)
$newArr[] = $row;
}
}
print_r($newArr);
$result = array();
foreach($input as $i){
if($i['SocketDecimal']==50)
$result[]=$i;
}
You can do it by this method
foreach ($yourarray as $key => $value){
$newarray = array("SocketDecimal"=>$value["SocketDecimal"];
}
print_r($newarray);
If your result array is like given below
$arr = array(
array( 'SocketID' => 1, 'SocketName' => 'Name', 'SocketDecimal' => 0, 'SocketHex' => 0, 'SocketAtt' => 1, 'Category' => 1, 'Value' => 100, 'Procentage' => 0 ),
array ( 'SocketID' => 2, 'SocketName' => 'Name2', 'SocketDecimal' => 50, 'SocketHex' => 32, 'SocketAtt' => 1, 'Category' => 1, 'Value' => 800, 'Procentage' => 0 ),
array ( 'SocketID' => 3, 'SocketName' => 'Name3', 'SocketDecimal' => 100, 'SocketHex' => 64, 'SocketAtt' => 1, 'Category' => 1, 'Value' => 60, 'Procentage' => 0 )
);
print_r($arr);
Get row for SocketDecimal=50 by following loop:
<pre>
$resultArr = '';
foreach($arr as $recordSet)
{
if($recordSet['SocketDecimal'] == 50)
{
$resultArr[] = $recordSet;
break;
}
}
</pre>
print_r($resultArr);
break foreach loop so that it will not traverse for all the array when SocketDecimal(50) founded.
You can use array_column + array_search combo
$array = Array (
"0" => Array ( "SocketID" => 1, "SocketName" => "Name", "SocketDecimal" => 0, "SocketHex" => 00, "SocketAtt" => 1, "Category" => 1, "Value" => 100, "Procentage" => 0 ) ,
"1" => Array ( "SocketID" => 2, "SocketName" => "Name2", "SocketDecimal" => 50, "SocketHex" => 32, "SocketAtt" => 1, "Category" => 1, "Value" => 800, "Procentage" => 0 ),
"2" => Array ( "SocketID" => 3, "SocketName" => "Name3", "SocketDecimal" => 100, "SocketHex" => 64, "SocketAtt" => 1, "Category" => 1, "Value" => 60 ,"Procentage" => 0 )
);
var_dump($array[array_search(50,array_column($array,'SocketDecimal'))]);

Summing The Contents Of A Three Tiered Array PHP

This is the array I am using (3 tiers), and I am trying to add the number of sales (nosales) from the first month in the first array to the first month in the second array (Should be 150) and so on through all the variables (months shouldn't be added) so I am left with a two level array with the nosales, salevalue,salecost and saleprofit totals for each month.
Array (
[0] => Array
(
[1] => Array
(
[month] => 1
[nosales] => 100
[salevalue] => 1200
[salecost] => 360
[saleprofit] => 840
)
[2] => Array
(
[month] => 2
[nosales] => 110
[salevalue] => 1320
[salecost] => 396
[saleprofit] => 924
)
)
[1] => Array
(
[1] => Array
(
[month] => 1
[nosales] => 50
[salevalue] => 350
[salecost] => 70
[saleprofit] => 280
)
[2] => Array
(
[month] => 2
[nosales] => 55
[salevalue] => 385
[salecost] => 77
[saleprofit] => 308
)
)
)
Now, I have tried looping through them to get them to add together but I am getting a number of errors. Could someone please help?
Here is the script I am using at the moment:
$acc = array_shift($results_array);
foreach ($results_array as $val) {
foreach ($val as $v) {
foreach ($v as $key => $v){
$acc[$key] += $v;
}
}
}
Thanks for your help in advance!
Is this what you wanted to do?
$aResultsArray = array(
0 => array(
1 => array(
'month' => 1,
'nosales' => 100,
'salevalue' => 1200,
'saleconst' => 360,
'saleprofit' => 840,
),
2 => array(
'month' => 2,
'nosales' => 110,
'salevalue' => 1320,
'saleconst' => 396,
'saleprofit' => 924,
),
),
1 => array(
1 => array(
'month' => 1,
'nosales' => 50,
'salevalue' => 350,
'saleconst' => 70,
'saleprofit' => 280,
),
2 => array(
'month' => 2,
'nosales' => 55,
'salevalue' => 385,
'saleconst' => 77,
'saleprofit' => 308,
),
),
);
$aSum = array();
foreach ($aResultsArray as $mYear => $aMonths) {
foreach ($aMonths as $mMonth => $aMonth) {
if (!isset($aSum[$aMonth['month']])) {
$aSum[$aMonth['month']] = array(
'month' => $aMonth['month'],
'nosales' => 0,
'salevalue' => 0,
'saleconst' => 0,
'saleprofit' => 0,
);
}
$aSum[$aMonth['month']]['nosales'] += $aMonth['nosales'];
$aSum[$aMonth['month']]['salevalue'] += $aMonth['salevalue'];
$aSum[$aMonth['month']]['saleconst'] += $aMonth['saleconst'];
$aSum[$aMonth['month']]['saleprofit'] += $aMonth['saleprofit'];
}
}
var_dump($aSum);

Categories