I have an array with date and some total.
I would like to sum all A_Total ; B_Total ; C_Total that have the same Date.
How can I do that ?
Thanks for the help
Source :
Array ( [0] => Array ( [Date] => 2022-10-23 [A_Total] => 547 [B_Total] => 70 [C_Total] => 83 ) [1] => Array ( [Date] => 2022-10-24 [A_Total] => 547 [B_Total] => 70 [C_Total] => 83 ) [2] => Array ( [Date] => 2022-10-25 [A_Total] => 552 [B_Total] => 70 [C_Total] => 83 ) [3] => Array ( [Date] => 2022-10-23 [A_Total] => 5 [B_Total] => 1 [C_Total] => 19 ) [4] => Array ( [Date] => 2022-10-24 [A_Total] => 5 [B_Total] => 1 [C_Total] => 19 ) [5] => Array ( [Date] => 2022-10-25 [A_Total] => 5 [B_Total] => 1 [C_Total] => 19 ) [6] => Array ( [Date] => 2022-10-23 [A_Total] => 557 [B_Total] => 134 [C_Total] => 51 ) [7] => Array ( [Date] => 2022-10-24 [A_Total] => 557 [B_Total] => 134 [C_Total] => 51 ) [8] => Array ( [Date] => 2022-10-25 [A_Total] => 557 [B_Total] => 134 [C_Total] => 51 ) )
Expected :
Array ( [0] => Array ( [Date] => 2022-10-23 [A_Total] => 1019 [B_Total] => 205 [C_Total] => 153 ) [1] => Array ( [Date] => 2022-10-24 [A_Total] => 1019 [B_Total] => 205 [C_Total] => 153 ) [2] => Array ( [Date] => 2022-10-25 [A_Total] => 1114 [B_Total] => 205 [C_Total] => 153 ) )
2
Answers
First get all values for each column
Then, you could use
array_sum
:In short:
References:
https://www.php.net/manual/en/function.array-sum.php
https://www.php.net/manual/en/function.array-column.php
Edit~
Grouping columns by date:
It will be a lot easier if you just make your array use the dates for keys. I mean, you’re trying to get the data grouped by dates anyway, so why not use the date as an identifier? Say you have this array:
Let’s create a buffer array, then go through the source array and write the values from it to the new array:
Let’s go through each bit. First,
foreach
will iterate over the array and return each element to whatever variable you specify, in this case,$s
:and
$s
has the entire element. So let’s get the date from that element:We’ll need to make sure that the buffer array has an element that matches this date, so let’s use
isset
to see, and if it doesn’t, then we’ll create an array that contains all of the keys we’ll need ('A_Total'
,'B_Total'
,'C_Total'
) using the date as the key:You didn’t say which version of php you’re using, and there are multiple ways to check for existence, and the later your version of php the easier they are to use, but
isset
is going to work for just about any version.!
is just the logical NOT operator, to invert the truth value coming fromisset
. In plain english, all we are saying is "If not set" and we specify the buffer element we are checking, and the action to take if the condition evaluates to true is inside the curly braces. If the element IS present (set), then we don’t take any action, because all we’re doing with this buffer is holding the old values and adding each new value to to old sum.Now we have a buffer array that has an element that matches our date. All we need to do is write the data from the current element of the source array (
$s
) to the buffer array, where += is just shorthand for "add this value to whatever is there already". It’s why we set the values to 0 in the array initialization:and after the
foreach
finishes looping, you’ll end up with this:But what if you didn’t know the keys ahead of time, or later you added some, or you wanted to reuse the code for any set of keys, and you didn’t want to have to hard code A_Total, B_Total, etc in every time you made a change? With some slight modifications, it’s no problem:
So, again we have the creation of a buffer array, and then we use
foreach
to loop over the source array, with each element assigned to$s
inside the loop. That’s all the same. And extracting the date and checking for the existence of the key in the buffer array is also the same. But this time, when we initialize each element in the buffer array, instead of hardcoding the keys and values, we just assign an empty array[]
to the element.and then we can use a variation of
foreach
to access both the key name and the value of each element by passing it two variable names instead of one:Now, inside each loop I’ll have both the key name (
A_Total
, for instance) and the value (547
), and I can just add the value the same way, with +=. However, in this case, since the buffer element was only an empty array, with no keys, we’ll have to do a little work to make sure that the buffer element has a key that matches our current loop. It’s just like we did before, withisset
, except now we’re checking to see ifA_Total
exists in the buffer for this date, and if not, we’ll create it and set it to 0:before adding the current value to it:
Now, I did skip one thing I did. The element of the source array that we’re working with (
$s
) also includes the date as one of its elements, so iterating it withforeach($s as $key=>$val)
is going to include that element. To avoid that, Iunset
the date element after I extracted it:And that’s it. It would work for any set of keys now, and any set of dates, whether you know them ahead of time or not. There’s a few ways to get the same result, using array_map or array_reduce. PHP has a lot of array handling methods, so if you’re going to spend any time working in it, you should check them out. For instance, I notice that all your keys are the same, and ‘Date’ is always the first one. So I could get an array of all the values EXCEPT that one using
array_slice
, where I’m passing the first element of the source array ($source[0]
) and telling it to return everything starting at element 1 (arrays are 0 indexed, so I’m telling it to skip the first one):which would give you this:
You could take that same thing, and extract the keys from it using
array_keys
and pass that toarray_fill_keys
:and end up with this:
which you’ll notice is the same array that we hard-coded in the very first example. You could also extract the dates from the source data like so:
These aren’t unique, but you could either use
array_flip
so that the values and keys switch places, resulting in an array where the keys are the unique dates, OR you could take that array we constructed just a second ago ($empties
):and use the
array_fill_keys
trick again to construct the buffer array completely:Then you wouldn’t need to perform the
isset
checks, since you know the buffer already has the necessary keys:You could create the buffer array entirely in one pass, without needing to construct the intermediary
$empties
array, but it is useful to have, because$empties
has the key names that you’ll want to extract from the source array, which is why I iterated thearray_keys
in this line:so that I could use
$k
(the key name, eg: A_Total) with$s
to get each value,$s[$k]
.Anyway, sorry for the long winded answer. It was probably more than you were asking for. Hope it makes a little sense, and helps. The main takeaway is that if you want to group them by date, just use an array that uses the dates as its keys. It makes everything a lot simpler.