SUM values across two multidimensional arrays in PHP - php

I have a problem how to SUM values of two multidimensional arrays in PHP.
Two arrays are storred in variables for example $array_1 and $array_2
Both $array_1 and $array_2 have sub-arrays, which again have data stored in their respective arrays. Notice that data is organized as x-data and y-data, where y-data is just a DATE stamp.
I need to SUM x-data values of these two arrays $array_1 and $array_2, with respect to y-data (DATE) dimension. This is why it got tricky for me, the closes answers I have found have only numbers.
Example:
$array_1
Array
(
[0] => object
(
[x-data] => Array
(
[data1] => 0
[data2] => 1
[data3] => 2
[data4] => 3
[data5] => 4
[data6] => 5
[data7] => 6
[data8] => 7
)
[y-data] => Array
(
[date] => 20141127
)
)
[1] => object
(
[x-data] => Array
(
[data1] => 2
[data2] => 4
[data3] => 6
[data4] => 8
[data5] => 10
[data6] => 12
[data7] => 14
[data8] => 16
)
[y-data] => Array
(
[date] => 20141128
)
)
)
$array_2
Array
(
[0] => object
(
[x-data] => Array
(
[data1] => 0
[data2] => 1
[data3] => 2
[data4] => 3
[data5] => 4
[data6] => 5
[data7] => 6
[data8] => 7
)
[y-data] => Array
(
[date] => 20141127
)
)
[1] => object
(
[x-data] => Array
(
[data1] => 0
[data2] => 1
[data3] => 2
[data4] => 3
[data5] => 4
[data6] => 5
[data7] => 6
[data8] => 7
)
[y-data] => Array
(
[date] => 20141128
)
)
)
$result = $array_1 + $array_2 should look like this:
Array
(
[0] => object
(
[x-data] => Array
(
[data1] => 0
[data2] => 2
[data3] => 4
[data4] => 6
[data5] => 8
[data6] => 10
[data7] => 12
[data8] => 14
)
[y-data] => Array
(
[date] => 20141127
)
)
[1] => object
(
[x-data] => Array
(
[data1] => 2
[data2] => 5
[data3] => 8
[data4] => 11
[data5] => 14
[data6] => 17
[data7] => 20
[data8] => 23
)
[y-data] => Array
(
[date] => 20141128
)
)
)
I have tried some things, like foreach() inside foreach() but I got a multiplication effect of the array values (2 x 2 = 4 subarrays instead of 2).
Any help?
Thanks!

Here's a partial answer as this should only only work if $array1 and $array2 have same number of elements and have unique y-datas, and each of their x-data (with y-data in common) have the same number of elements.
$result = array_multisum($array1, $array2);
function array_multisum($array1, $array2)
{
$newArray = array();
foreach ($array1 as $object1) {
$newObject = new stdClass();
// find object in the 2nd array having the same data as current object
foreach ($array2 as $object2) {
// if object is found, sum the x-data with the current object
if ($object1->{'y-data'}['date'] === $object2->{'y-data'}['date']) {
$newObject->{'x-data'} = data_sum($object1->{'x-data'}, $object2->{'x-data'});
break;
}
}
$newObject->{'y-data'} = $object1->{'y-data'};
$newArray[] = $newObject;
}
return $newArray;
}
function data_sum($data1, $data2)
{
$newData = array();
// sum up the values for each key
foreach (array_keys($data1) as $key) {
$newData[$key] = $data1[$key] + $data2[$key];
}
return $newData;
}

Related

Split the array in to sub arrays based on array key value [duplicate]

This question already has answers here:
How to group subarrays by a column value?
(20 answers)
Closed 1 year ago.
I am facing one issue while splitting array by key value. My array looks like below :-
Array
(
[0] => Array
(
[product_id] => 6
[brand_id] => 2
)
[1] => Array
(
[product_id] => 1
[brand_id] => 1
)
[2] => Array
(
[product_id] => 5
[brand_id] => 1
)
)
Now i want to filter split the array based on brand_id. My expected output is like below:-
Array(
[0] => Array(
[0] => Array
(
[product_id] => 6
[brand_id] => 2
)
)
[1] => Array(
[0] => Array
(
[product_id] => 1
[brand_id] => 1
)
[1] => Array
(
[product_id] => 5
[brand_id] => 1
)
)
)
My Input array is stored in $proArray variable
My attempt below:-
$brands = array();
foreach ($proArr as $key => $pro) {
$brands[] = $pro['brand_id'];
}
$brands = array_unique($brands);
$ckey = 0;
foreach($brands as $brand){
}
One way to do it with simple foreach() loop to push values based on your brand_id like below-
$key = 'brand_id';
$return = array();
foreach($array as $v) {
$return[$v[$key]][] = $v;
}
print_r($return);
WORKING DEMO: https://3v4l.org/bHuWV
Code:
$arr = array(
array(
'product_id' => 6,
'brand_id' => 2
),
array(
'product_id' => 1,
'brand_id' => 1
),
array(
'product_id' => 5,
'brand_id' => 1
)
);
$res = [];
foreach ($arr as $key => $value)
$res[$value['brand_id']][] = $value;
$res = [...$res];
print_r($res);
Output:
Array
(
[0] => Array
(
[0] => Array
(
[product_id] => 6
[brand_id] => 2
)
)
[1] => Array
(
[0] => Array
(
[product_id] => 1
[brand_id] => 1
)
[1] => Array
(
[product_id] => 5
[brand_id] => 1
)
)
)

Array_push within foreach loop overwites earlier arrey values

I'm trying to build a multidimentional array of matches found within a foreach loop. After one loop the array is correct but on the second loop, the earlier array values are overwritten. What is going on?
$matches = array();
foreach ($promotions as $promotion) {
$matches = array();
foreach ($saleitems as $saleitem) {
if ($saleitem['PROMO_CODE'] == $promotion['SALES_CODE']) {
$matches[] = array('ID'=>$saleitem['ID'], "LINENO"=>$saleitem['LINE'], "SAVING"=>"0", 'SALEINC'=>$saleitem['SALEINC']);
}
}
//other code with works out discount etc.
$linesarray[] = array("CODE"=>$promotion['CODE'], "LINES"=>$matches);
print_r($linesarray);
echo "<p>";
}
Outputs this:
Array ( [0] => Array ( [CODE] => 5 [LINES] => Array ( [0] => Array ([ID] => 51016 [LINENO] => 4 [SAVING] => 5 [SALEINC] => 15.00 ) [1] => Array ([ID] => 51013 [LINENO] => 3 [SAVING] => 5 [SALEINC] => 15.00 ) ) ) )
Array ( [0] => Array ( [CODE] => 5 [LINES] => Array ( [0] => Array ( [ID] => 51016 [LINENO] => 4 [SAVING] => 5 [SALEINC] => 15.00 ) [1] => Array ([ID] => 43930 [LINENO] => 2 [SAVING] => 0 [SALEINC] => 16.00 ) ) ) [1] => Array ( [CODE] => 7 [LINES] => Array ( [0] => Array ([ID] => 43914 [LINENO] => 1 [SAVING] => 6 [SALEINC] => 16.00 ) [1] => Array ([ID] => 43930 [LINENO] => 2 [SAVING] => 6 [SALEINC] => 16.00 ) ) ) )
As you can see LINENO 3 has been replaced the first array on second loop. Why?
The $matches = array(); inside the loop will reinitialize the array. The $matches = array(); before the loop is fine.
$matches[] = array('ID'=>$saleitem['ID'], "LINENO"=>$saleitem['LINE'], "SAVING"=>"0", 'SALEINC'=>$saleitem['SALEINC']);
I see you fixed "SAVING"=>"0" but your outputs have other result [SAVING] => 5 Did you run your code again?
You should give us $promotions and $saleitems array.

Find a value & key in a multidimensional array [duplicate]

This question already has answers here:
Find value and key in multidimensional array
(8 answers)
Closed 9 years ago.
I have 2 arrays, I need to find if one of the values in array one matches one of the values in array two, a multi-dimensional array. I also need to check that the value from array one is in a specific key in array two, the "principal" key as the "authority" key may also hold this value.
here is array one:
Array
(
[0] => 17
[1] => 6
[2] => 3
[3] => 2
)
and array two [actually slightly truncated for readability]:
Array
(
[modAccessResourceGroup] => Array
(
[3] => Array
(
[0] => Array
(
[principal] => 0
[authority] => 9999
[policy] => Array
(
[load] => 1
)
)
[1] => Array
(
[principal] => 2
[authority] => 10
[policy] => Array
(
[add_children] => 1
[create] => 1
[copy] => 1
[delete] => 1
[list] => 1
[load] => 1
[move] => 1
[publish] => 1
[remove] => 1
[save] => 1
[steal_lock] => 1
[undelete] => 1
[unpublish] => 1
[view] => 1
)
)
.... truncated ....
[13] => Array
(
[principal] => 16
[authority] => 9999
[policy] => Array
(
[load] => 1
)
)
)
[8] => Array
(
[0] => Array
(
[principal] => 0
[authority] => 9999
[policy] => Array
(
[load] => 1
)
)
[1] => Array
(
[principal] => 1
[authority] => 9999
[policy] => Array
(
[add_children] => 1
[create] => 1
[copy] => 1
[delete] => 1
[list] => 1
[load] => 1
[move] => 1
[publish] => 1
[remove] => 1
[save] => 1
[steal_lock] => 1
[undelete] => 1
[unpublish] => 1
[view] => 1
)
)
[2] => Array
(
[principal] => 22
[authority] => 9999
[policy] => Array
(
[add_children] => 1
[create] => 1
[copy] => 1
[delete] => 1
[list] => 1
[load] => 1
[move] => 1
[publish] => 1
[remove] => 1
[save] => 1
[steal_lock] => 1
[undelete] => 1
[unpublish] => 1
[view] => 1
)
)
)
)
)
I was using a series of foreach(){foreach(){foreach(){}}} but it seemed very messy and inefficient. Having some trouble getting my head around this. Any ideas?
A recursive function should do the trick:
$values = array(17, 6, 3, 2, 5);
function find($array, &$values) {
foreach ($array as $key => $element) {
if (is_array($element)) {
find($element, $values);
}
elseif ($key == 'principal') {
foreach ($values as $value) {
if ($element == $value) {
echo 'Found' . PHP_EOL;
// Do stuff
}
}
}
}
}
find($array, $values);
Several things come to mind. First, in situations like this, I will usually create a separate array with just the principal values so that I can loop over the first array and just use a simple in_array() check. Secondly, if you don't want to do that, you could do something using the array_walk_recursive() function or some of the recursive examples in array_search() to go through your second array.

How to combine arrays from a multidimensional array and count values?

I'm a beginner at php and was searching for a solution all day long without success.
I have the following array:
$data = Array
(
[0] => Array
(
[my_id] => 1
[my_post_id] => 123
[my_status] => 1
[my_rating] => 5
)
[1] => Array
(
[my_id] => 2
[my_post_id] => 123
[my_status] => 1
[my_rating] => 4
)
[2] => Array
(
[my_id] => 3
[my_post_id] => 123
[my_status] => 1
[my_rating] => 5
)
[3] => Array
(
[my_id] => 4
[my_post_id] => 456
[my_status] => 1
[my_rating] => 5
)
[4] => Array
(
[my_id] => 5
[my_post_id] => 456
[my_status] => 1
[my_rating] => 3
)
)
and would like to merge the arrays with the same 'my_post_id' and count the values for 'my_status' and 'my_rating' which have the same 'my_post_id'.
At the end, I would like to have the following array:
$data = Array
(
[0] => Array
(
[my_post_id] => 123
[my_status] => 3
[my_rating] => 14
)
[1] => Array
(
[my_post_id] => 456
[my_status] => 2
[my_rating] => 8
)
)
I could get arrays with unique 'my_post_id' with the following code but I couldn't find out how to count the other values.
$out = array();
foreach( $data as $row ) {
$out[$row['my_post_id']] = $row;
}
$array = array_values( $out );
Any help would be much appreciated.
Daniel
This will produce the array you are looking for:
$out = array();
foreach( $data as $row ) {
if (!isset($out[$row['my_post_id']])) {
$out[$row['my_post_id']] = Array( "my_id"=>$row['my_id'],
"my_status" => $row["my_status"],
"my_rating" => $row["my_rating"]);
}
else {
$out[$row['my_post_id']]["my_status"] += $row["my_status"];
$out[$row['my_post_id']]["my_rating"] += $row["my_rating"];
}
}
results in:
Array
(
[123] => Array
(
[my_id] => 1
[my_status] => 3
[my_rating] => 14
)
[456] => Array
(
[my_id] => 4
[my_status] => 2
[my_rating] => 8
)
)
try the following - untested code
foreach($data as $key => $val){
if(!array_search($val['my_post_id'],$newArray)){
$newArray[]=array('my_post_id' => $val['my_post_id'],
'my_status' => $val['my_status'],
'my_rating' => $val['my_rating']);
}else{
$myIndex=array_search($val['my_post_id'],$newArray);
$newArray[$myIndex]['my_status']+=$val['my_status'];
$newArray[$myIndex]['my_rating']+=$val['my_rating'];
}
}

How do i merge the arrays in a particular format?

I have following arrays:
1) for total placed
Array
(
[0] => Array
(
[centers] => Array
(
[name] => delhi
[id] => 1
)
[0] => Array
(
[totalplaced] => 8
)
)
[1] => Array
(
[centers] => Array
(
[name] => mumbai
[id] => 2
)
[0] => Array
(
[totalplaced] => 1
)
)
)
2) for total working
Array
(
[0] => Array
(
[centers] => Array
(
[name] => delhi
[id] => 1
)
[0] => Array
(
[totalworking] => 4
)
)
[1] => Array
(
[centers] => Array
(
[name] => mumbai
[id] => 2
)
[0] => Array
(
[totalworking] => 1
)
)
)
3) for total trained
Array
(
[0] => Array
(
[centers] => Array
(
[name] => delhi
[id] => 1
)
[0] => Array
(
[totaltrained] => 8
)
)
[1] => Array
(
[centers] => Array
(
[name] => mumbai
[id] => 2
)
[0] => Array
(
[totaltrained] => 1
)
)
)
I wanted to merge these arrays so that the resultant array should look like this
[newarray] => Array(
[0] => Array (
[centers] => Array
(
[name] => delhi
[id] => 1
[totalplaced] => 8
[totalworking] => 4
[totaltrained] => 8
)
)
[1]=> Array(
[centers] => Array
(
[name] => mumbai
[id] => 2
[totalplaced] => 1
[totalworking] => 1
[totaltrained] => 1
)
)
)
This is the tabular representation of the above data which i want to display
centername totalplaced totalworking totaltrained
delhi 8 4 8
mumbai 1 1 1
Please help me on this.
Thanks
Pankaj Khurana
The difficulty here is that PHP's functions such as array_merge() and array_merge_recursive() will not merge data into numeric keys, but rather will re-key any duplicate numeric key. So for example given two arrays:
array(
'test' => 'abc',
0 => 'xyz'
);
array(
'test' => 'def',
0 => 'uvw'
);
Merging them together with array_merge() will produce an array like:
array(
'test' => 'def',
0 => 'xyz',
1 => 'uvw'
);
So, you need a custom function to be "additive" on any key, regardless of whether it is a string or numeric key. Try this:
function mixed_key_array_merge() {
$args = func_get_args();
$result = array();
foreach ($args as $arg) {
// discard non-array arguments; maybe this could be better handled
if (!is_array($arg)) {
continue;
}
foreach ($arg as $key => $value) {
if (!isset($result[$key])) {
$result[$key] = $value;
} else if (is_array($result[$key])) {
$result[$key] = call_user_func_array('mixed_key_array_merge',array($result[$key],$value));
}
}
}
return $result;
}

Categories