Sum values in multi dimensional array - php

I'm trying to display the total amount of installs each campaign number has had since the beginning using this array.
Array
(
[27] => Array
(
[0] => Array
(
[date] => 2018-04-09
[hour] => 7
[campaign] => 27
[installs] => 2
[trials] => 0
)
[1] => Array
(
[date] => 2018-04-09
[hour] => 3
[campaign] => 39
[installs] => 1
[trials] => 0
)
[2] => Array
(
[date] => 2018-04-09
[hour] => 5
[campaign] => 39
[installs] => 1
[trials] => 0
)
[3] => Array
(
[date] => 2018-04-09
[hour] => 6
[campaign] => 39
[installs] => 1
[trials] => 0
)
[4] => Array
(
[date] => 2018-04-09
[hour] => 8
[campaign] => 39
[installs] => 2
[trials] => 0
)
)
[53] => Array
(
[0] => Array
(
[date] => 2018-04-10
[hour] => 3
[campaign] => 53
[installs] => 1
[trials] => 0
)
[1] => Array
(
[date] => 2018-04-10
[hour] => 9
[campaign] => 53
[installs] => 1
[trials] => 0
)
[2] => Array
(
[date] => 2018-04-10
[hour] => 5
[campaign] => 55
[installs] => 1
[trials] => 0
)
[3] => Array
(
[date] => 2018-04-10
[hour] => 12
[campaign] => 55
[installs] => 1
[trials] => 0
)
)
[61] => Array
(
[0] => Array
(
[date] => 2018-04-15
[hour] => 0
[campaign] => 61
[installs] => 27
[trials] => 1
)
[1] => Array
(
[date] => 2018-04-15
[hour] => 1
[campaign] => 61
[installs] => 18
[trials] => 0
)
[2] => Array
(
[date] => 2018-04-15
[hour] => 1
[campaign] => 27
[installs] => 10
[trials] => 0
)
My array is shown above. You can see some of the campaign numbers are repeated on different dates. My result should look like:
Campaign 27: 12
Campaign 39: 5
Campaign 53: 2
Campaign 55: 2
Campaign 61: 45
So far I've got this, which doesn't seem to be printing all of the data.
$newarray = array();
$last = count($res) - 1;
foreach ($res as $i => $new){
foreach ($new as $x => $row){
$isFirst = ($i == 0);
$isLast = ($i == $last);
$grabbedvalue = $row['campaign'].",".$row['installs'];
array_push($newarray,$grabbedvalue);
}
}
print_r($newarray);
Hope that someone can help me out with this. Thanks!

Just loop through the array and count:
$data = [
[
'campaign' => 1,
'installs' => 20,
],
[
'campaign' => 1,
'installs' => 5,
],
[
'campaign' => 2,
'installs' => 1,
],
[
'campaign' => 2,
'installs' => 10,
],
[
'campaign' => 3,
'installs' => 9,
],
];
$count=array();
// Loop through the campaigns
foreach($data as $camp){
// Check if we initiated the counting before
if(isset($count[$camp['campaign']])){
// Add installs count to previous value
$count[$camp['campaign']] += $camp['installs'];
} else {
// Initiate the counting
$count[$camp['campaign']] = $camp['installs'];
}
}
var_dump($count);
This will give:
array (size=3)
1 => int 25
2 => int 11
3 => int 9

You should create a for loop inside of a for loop to solve this.
I can try explaining the steps as clearly as possible:
Create an new array ($totalInstalls)
Loop trough the array you specified
Loop trough each element in the array you specified (for loop inside a for loop)
Check if the campaign index of the current element already exists in $totalInstalls
If not set it to the installs
If it does exists increment it by one

Related

Join Two arrays in php

I have two arrays and the First array name is $balances and output is below:
Array
(
[0] => Array
(
[index] => 0
[account_id] => 1
[company_id] => 6
[company_code] => ABBANK
)
[1] => Array
(
[index] => 6
[account_id] => 1
[company_id] => 147
[company_code] => IFIC
)
[2] => Array
(
[index] => 11
[account_id] => 1
[company_id] => 293
[company_code] => SOUTHEASTB
)
)
Second array name is $market and it's output:
Array
(
[0] => Array
(
[company] => SOUTHEASTB
[high] => 0
[low] => 0
)
[1] => Array
(
[company] => IFIC
[high] => 0
[low] => 0
)
[2] => Array
(
[company] => ABBANK
[high] => 0
[low] => 0
)
)
I merge this two array and getting bellow output. The 2nd array push the array value to 1st array using the code below producing a result which is not in my requirement:
$result = array();
foreach ($balances as $key => $value) {
$result[] = array_merge($value, $market[$key]);
}
Output:
Array
(
[0] => Array
(
[index] => 0
[company_code] => ABBANK
[company] => 1JANATAMF
[high] => 5.3
[low] => 5
)
[1] => Array
(
[index] => 6
[company_code] => IFIC
[company] => 1STPRIMFMF
[high] => 16.9
[low] => 16.2
)
[2] => Array
(
[index] => 11
[company_code] => SOUTHEASTB
[company] => AAMRANET
[high] => 44
[low] => 43
)
)
My challenge to check the $balances[company_code] == $market['company'] and append the 2nd array to 1st array which will produce the following result.
Array
(
[0] => Array
(
[index] => 0
[account_id] => 1
[company_id] => 6
[company_code] => ABBANK
[high] => 0
[low] => 0
)
[1] => Array
(
[index] => 6
[account_id] => 1
[company_id] => 147
[company_code] => IFIC
[high] => 0
[low] => 0
)
[2] => Array
(
[index] => 11
[account_id] => 1
[company_id] => 293
[company_code] => SOUTHEASTB
[high] => 0
[low] => 0
)
)
But above code block is not serving my demand. Because this code block only push the second array to 1st array using merge function. I tried every other solution in my stock. Is there anyone who can give me any solution will be highly appreciated.
This can be solved in minimal code by using array_column to re-index both arrays by the company name, the two arrays can then be merged using array_merge_recursive:
$output = array_merge_recursive(array_column($balances, null, 'company_code'),
array_column($market, null, 'company'));
Output:
Array
(
[ABBANK] => Array
(
[index] => 0
[account_id] => 1
[company_id] => 6
[company_code] => ABBANK
[company] => ABBANK
[high] => 0
[low] => 0
)
[IFIC] => Array
(
[index] => 6
[account_id] => 1
[company_id] => 147
[company_code] => IFIC
[company] => IFIC
[high] => 0
[low] => 0
)
[SOUTHEASTB] => Array
(
[index] => 11
[account_id] => 1
[company_id] => 293
[company_code] => SOUTHEASTB
[company] => SOUTHEASTB
[high] => 0
[low] => 0
)
)
If you want a numerically indexed result, just pass $output through array_values.
$output = array_values($output);
Demo on 3v4l.org
I have taken two arrays '$a' and '$b', in your case it is $balances and $market, respectively. array_push() is the simplest thing you can do to push/append values of array '$b' to array '$a'.
$a = array(array(
"index" => 0,
"account_id" => 1,
"company_id" => 6,
"company_code" => "ABBANK"
),
array
(
"index" => 6,
"account_id" => 1,
"company_id" => 147,
"company_code" => "IFIC"
),
array
(
"index" => 11,
"account_id" => 1,
"company_id" => 293,
"company_code" => "SOUTHEASTB"
));
$b = array
(
array
(
"company" => "SOUTHEASTB",
"high" => 0,
"low" => 0,
),
array
(
"company" => "IFIC",
"high" => 0,
"low" => 0,
),
array
(
"company" => "ABBANK",
"high" => 0,
"low" => 0
)
);
$result = array();
foreach($a as $key=>$value){
foreach($b as $key2 => $value2){
if($value['company_code'] === $value2['company']){
//append matched part of $b array to $a array value
array_push($value,$value2['high'],$value2['low']);
//append to result array
array_push($result, $value);
}
}
}
print_r($result);
//Output
Array
(
[0] => Array
(
[index] => 0
[account_id] => 1
[company_id] => 6
[company_code] => ABBANK
[0] => 0
[1] => 0
)
[1] => Array
(
[index] => 6
[account_id] => 1
[company_id] => 147
[company_code] => IFIC
[0] => 0
[1] => 0
)
[2] => Array
(
[index] => 11
[account_id] => 1
[company_id] => 293
[company_code] => SOUTHEASTB
[0] => 0
[1] => 0
)
)
While Nick's three-function approach is certainly attractive for its brevity, be aware that it stores the relating elements from both arrays (has redundant data in the output) and makes three iterating cycles.
A less concise alternative that doesn't require a recursive call is to forge a lookup array with one cycle (foreach()) and remove the unwanted element from the lookup, then iterate the balances array and swiftly merge related data set based on share company name values.
This assumes that the balances array should dictate which market values should be included in the result.
Code: (Demo)
$lookup = [];
foreach ($market as $row) {
$lookup[array_shift($row)] = $row;
}
var_export(
array_map(
fn($row) => $row + ($lookup[$row['company_code']] ?? []),
$balances
)
);

php - sorting by points and then alphabetically

I have an array:
Array (
[0] => Array
( [points] => 10
[id] => 58
[nazwa] => auser1 )
[1] => Array
( [points] => 15
[id] => 36
[nazwa] => cuser2 )
[2] => Array
( [points] => 15
[id] => 57
[nazwa] => buser3 )
[3] => Array
( [points] => 20
[id] => 56
[nazwa] => duser4 )
[4] => Array
( [points] => 20
[id] => 54
[nazwa] => euser5 ))
I would like to sort this array by points and then alphabetically by nazwa.
How can I do this?
I would like to create final points table for Russia Cup!
if you want to sort your multidimensional array in sequence first points then with name then you have to create your multidimensional array in same sequence format
example: first element should be points, second name, last id. Refer following sequence.
$array = [ [ 'points' => 10, 'nazwa' => 'auser1', 'id' => 58 ],
[ 'points' => 15, 'nazwa' => 'cuser2', 'id' => 36 ],
[ 'points' => 15, 'nazwa' => 'buser3', 'id' => 57 ],
[ 'points' => 20, 'nazwa' => 'duser4', 'id' => 56 ],
[ 'points' => 20, 'nazwa' => 'euser5', 'id' => 54 ]];
array_multisort( $array );
print_r(($array));
Output:
Array
(
[0] => Array
(
[points] => 10
[nazwa] => auser1
[id] => 58
)
[1] => Array
(
[points] => 15
[nazwa] => buser3
[id] => 57
)
[2] => Array
(
[points] => 15
[nazwa] => cuser2
[id] => 36
)
[3] => Array
(
[points] => 20
[nazwa] => duser4
[id] => 56
)
[4] => Array
(
[points] => 20
[nazwa] => euser5
[id] => 54
)
)

How to combine two array and chunk it if the key is same

I'am bulding an app with laravel, and I have a problem, I have two array in php :
Array1
(
[0] => 15
[1] => 15
[2] => 16
[3] => 16
[4] => 17
[5] => 17
[6] => 17
[7] => 17
)
Array2
(
[0] => 0
[1] => 1
[2] => 1
[3] => 2
[4] => 0
[5] => 1
[6] => 2
[7] => 3
)
in this case i can not to use array_chunk because the value of array2 is dinamic and key of array1 must not be same if i combine it, so, how i can combine it to be like this :
Array
(
[15] => Array
(
[0] => 0
[1] => 1
)
[16] => Array
(
[0] => 1
[1] => 2
)
[17] => Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
)
)
Simple foreach loop:
$arr1 = [15,15,16,16,17,17,17,17];
$arr2 = [0,1,1,2,0,1,2,3];
$result = [];
foreach($arr1 as $k => $v){
$result[$v][] = $arr2[$k];
}
print_r($result);
The output:
Array
(
[15] => Array
(
[0] => 0
[1] => 1
)
[16] => Array
(
[0] => 1
[1] => 2
)
[17] => Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
)
)
$array1 =
[
0 => 15,
1 => 15,
2 => 16,
3 => 16,
4 => 17,
5 => 17,
6 => 17,
7 => 17,
];
$array2 =
[
0 => 0,
1 => 1,
2 => 1,
3 => 2,
4 => 0,
5 => 1,
6 => 2,
7 => 3,
];
$arr = array_unique($array1);
print_r($arr);
$newarray = [];
foreach($arr as $ar){
foreach($array1 as $key => $value){
if($ar == $value){
$newarray[$value][] =$array2[$key];
}
}
}
print_r($newarray);

Extended code: Grouping multidimensional PHP array and calculating sum of a particular keys for each array element

This is actually a extended version of the original code posted by #RomanPerekhrest here: Grouping multidimensional PHP array and calculating sum of a particular key for each arrays element
I played with the code and tried to extend it to next level. And to some extent I succeeded.
What is did is that I added one more sub array called "holders" in addition to the existing "companies" sub array. And then calculated the sum of "capacity_share" from "companies" sub array and "holder_share" from "holders" sub array.
And it worked like a charm. I am adding the extended code below:
Consider the below array assigned to variable: $projects_group_by_year
Array
(
[2016] => Array
(
[0] => Array
(
[id] => 1
[project_name] => P1
[project_capacity] => 100
[year_actual] => 2016
[companies] => Array
(
[0] => Array
(
[id] => 1
[project_id] => 1
[company_type] => C1
[capacity_share] => 12
[project_year] => 2016
)
[1] => Array
(
[id] => 2
[project_id] => 1
[company_type] => C1
[capacity_share] => 14
[project_year] => 2016
)
),
[holders] => Array
(
[0] => Array
(
[id] => 1
[project_id] => 1
[holder_type] => H1
[holder_share] => 12
[project_year] => 2016
)
[1] => Array
(
[id] => 2
[project_id] => 1
[holder_type] => H2
[holder_share] => 14
[project_year] => 2016
)
)
)
[1] => Array
(
[id] => 2
[project_name] => P2
[project_capacity] => 200
[year_actual] => 2016
[companies] => Array
(
[0] => Array
(
[id] => 3
[project_id] => 2
[company_type] => C2
[capacity_share] => 15
[project_year] => 2016
)
[1] => Array
(
[id] => 4
[project_id] => 2
[company_type] => C1
[capacity_share] => 16
[project_year] => 2016
)
),
[holders] => Array
(
[0] => Array
(
[id] => 3
[project_id] => 2
[holder_type] => H1
[holder_share] => 12
[project_year] => 2016
)
[1] => Array
(
[id] => 4
[project_id] => 2
[holder_type] => H2
[holder_share] => 14
[project_year] => 2016
)
)
)
)
[2014] => Array
(
[0] => Array
(
[id] => 3
[project_name] => P3
[project_capacity] => 300
[year_actual] => 2014
[companies] => Array
(
[0] => Array
(
[id] => 5
[project_id] => 3
[company_type] => C1
[capacity_share] => 20
[project_year] => 2014
)
[1] => Array
(
[id] => 6
[project_id] => 3
[company_type] => C2
[capacity_share] => 22
[project_year] => 2014
)
),
[holders] => Array
(
[0] => Array
(
[id] => 5
[project_id] => 3
[holder_type] => H1
[holder_share] => 12
[project_year] => 2014
)
[1] => Array
(
[id] => 6
[project_id] => 3
[holder_type] => H2
[holder_share] => 14
[project_year] => 2014
)
)
)
[1] => Array
(
[id] => 4
[project_name] => P4
[project_capacity] => 400
[year_actual] => 2014
[companies] => Array
(
[0] => Array
(
[id] => 7
[project_id] => 4
[company_type] => C2
[capacity_share] => 11
[project_year] => 2014
)
[1] => Array
(
[id] => 8
[project_id] => 4
[company_type] => C1
[capacity_share] => 10
[project_year] => 2014
)
),
[holders] => Array
(
[0] => Array
(
[id] => 7
[project_id] => 4
[holder_type] => H1
[holder_share] => 12
[project_year] => 2014
)
[1] => Array
(
[id] => 8
[project_id] => 4
[holder_type] => H2
[holder_share] => 14
[project_year] => 2014
)
)
)
)
)
And using code below I get the perfect result:
$sumData = array_map('prepare_data', $projects_group_by_year);
print_r($sumData);
exit;
function prepare_data($v) {
$arr = ['year' => current(array_column($v, 'year_actual'))];
$arr['project_capacity_sum'] = array_sum(array_column($v, "project_capacity"));
$arr['C2_capacity_sum'] = $arr['C1_capacity_sum'] = 0;
$arr['H2_capacity_sum'] = $arr['H1_capacity_sum'] = 0;
foreach ($v as $item) {// iterating through the nested items
$c_capacities = array_column($item['companies'], 'capacity_share', 'company_type');
$arr['C1_capacity_sum'] += $c_capacities['C1'];
$arr['C2_capacity_sum'] += $c_capacities['C2'];
$h_shares = array_column($item['holders'], 'holder_share', 'holder_type');
$arr['H1_share_sum'] += $h_shares['H1'];
$arr['H2_share_sum'] += $h_shares['H2'];
}
return $arr;
}
But my code is not working well under two conditions:
First condition:
If I add all sub arrays with same [company_type] => value pair. Then it displays following notice:
Notice: Undefined index: C2
[companies] => Array
(
[0] => Array
(
[id] => 1
[project_id] => 1
[company_type] => C1 //Notice here
[capacity_share] => 12
[project_year] => 2016
)
[1] => Array
(
[id] => 2
[project_id] => 1
[company_type] => C1 //Notice here
[capacity_share] => 14
[project_year] => 2016
)
)
Second Condition:
If I add more than one sub array with same [company_type] => value pair, then it only considers the last [company_type] => value pair for adding the [capacity_share]. For example, it uses [capacity_share] => 15 in the case below and does not consider [capacity_share] => 14.
[companies] => Array
(
[0] => Array
(
[id] => 1
[project_id] => 1
[company_type] => C1
[capacity_share] => 12
[project_year] => 2016
)
[1] => Array
(
[id] => 2
[project_id] => 1
[company_type] => C2 //Notice here
[capacity_share] => 14
[project_year] => 2016
),
[2] => Array
(
[id] => 3
[project_id] => 1
[company_type] => C2 //Notice here
[capacity_share] => 15
[project_year] => 2016
)
)
I am working on fixing above issues for past few days.
Below is one of the code snippets I tried to make this work:
function prepare_data($v) {
$arr = ['year' => current(array_column($v, 'year_actual'))];
$arr['project_capacity_sum'] = array_sum(array_column($v, "project_capacity"));
$arr['C2_capacity_sum'] = $arr['C1_capacity_sum'] = 0;
$arr['H2_share_sum'] = $arr['H1_share_sum'] = 0;
foreach ($v as $item) {// iterating through the nested items
$c_capacities = array_column($item['companies'], 'capacity_share', 'company_type');
if(isset($c_capacities['company_type'])){
$arr['C1_capacity_sum'] += $c_capacities['company_type'];
}
if(isset($c_capacities['C2'])){
$arr['C2_capacity_sum'] += $c_capacities['C2'];
}
$h_shares = array_column($item['holders'], 'holder_share', 'holder_type');
$arr['H1_share_sum'] += $s_capacities['H1'];
$arr['H2_share_sum'] += $s_capacities['H2'];
}
return $arr;
}
Does any one know what I am doing wrong and how can I fix the above two issues?
Thanks.
And here is the solution :)
$sumData = array_map('prepare_data', $projects_grouped_by_year);
function prepare_data($v) {
$arr = ['year' => current(array_column($v, 'year_actual'))];
$arr['project_capacity_sum'] = array_sum(array_column($v, "project_capacity"));
$arr['C2_capacity_sum'] = $arr['C1_capacity_sum'] = 0;
$arr['H2_capacity_sum'] = $arr['H1_capacity_sum'] = 0;
foreach ($v as $item) {
// summing up companies shares
$c_types = array_column($item['companies'], 'company_type');
$c_shares = array_column($item['companies'], 'capacity_share');
foreach ($c_types as $k => $v) {
$arr[$v ."_capacity_sum"] += $c_shares[$k];
}
// summing up holders shares
$h_types = array_column($item['holders'], 'holder_type');
$h_shares = array_column($item['holders'], 'holder_share');
foreach ($h_types as $k => $v) {
$arr[$v ."_capacity_sum"] += $h_shares[$k];
}
}
return $arr;
}
print_r($sumData);

combine multidimentional associative arrays with matching key value pair

[traffic] => Array
(
[0] => Array
(
[id] => 1
[visitors] => 310
[pageviews] => 1333
[created_date] => 2016-03-09
)
[1] => Array
(
[id] => 2
[visitors] => 374
[pageviews] => 1010
[created_date] => 2016-03-10
)
[2] => Array
(
[id] => 3
[visitors] => 143
[pageviews] => 617
[created_date] => 2016-03-11
)
)
[source] => Array
(
[0] => Array
(
[created_date] => 2016-03-09
[scount] => 368
)
[1] => Array
(
[created_date] => 2016-03-10
[scount] => 550
)
[2] => Array
(
[created_date] => 2016-03-11
[scount] => 238
)
)
I have two multidimensional arrays, I want to combine both arrays into one with matching created_date value, the result should be like this,
Array
(
[0] => Array
(
[created_date] => 2016-03-09
[id] => 1
[visitors] => 310
[pageviews] => 1333
[scount] => 368
)
[1] => Array
(
[created_date] => 2016-03-10
[id] => 2
[visitors] => 374
[pageviews] => 1010
[scount] => 550
)
[2] => Array
(
[created_date] => 2016-03-11
[id] => 3
[visitors] => 143
[pageviews] => 617
[scount] => 238
)
)
$traffic = []; //...
$source = []; // ...
foreach($traffic as $key => $value)
{
if(isset($source[$key]))
{
$token = $source[$key];
foreach($token as $keyy => $valuee)
{
if(isset($traffic[$key][$keyy]))
{
// Collision handling, if any ...
$traffic[$key][$keyy] = $valuee;
}
else $traffic[$key][$keyy] = $valuee;
}
}
}
The following code should do the trick.
The solution:
# I split your array into 2 parts ($traffic = $your_array['traffic'])
$traffic = array(
array(
id => 1,
visitors => 310,
pageviews => 1333,
created_date => '2016-03-09'
),
array(
id => 2,
visitors => 374,
pageviews => 1010,
created_date => '2016-03-10'
),
array(
id => 3,
visitors => 143,
pageviews => 617,
created_date => '2016-03-11'
)
);
# I split your array into 2 parts ($source = $your_array['source'])
$source = array(
array (
created_date => '2016-03-09',
scount => 368
),
array (
created_date => '2016-03-10',
scount => 550
),
array (
created_date => '2016-03-11',
scount => 238
)
);
# copy the traffic array cause we want to merge the new data into it
$result = $traffic;
# loop over the traffic array
foreach ($traffic as $k => $t) {
# loop over the source
foreach ($source as $s) {
# try to find a match
if ($t['created_date'] === $s['created_date']) {
# add data to result
$result[$k]['scount'] = $s['scount'];
# we exit the inner foreach-loop here as there is only 1 match
break;
}
}
}
# print the result
echo '<pre>'; print_r($result); echo '</pre>';
The result:
Array
(
[0] => Array
(
[id] => 1
[visitors] => 310
[pageviews] => 1333
[created_date] => 2016-03-09
[scount] => 368
)
[1] => Array
(
[id] => 2
[visitors] => 374
[pageviews] => 1010
[created_date] => 2016-03-10
[scount] => 550
)
[2] => Array
(
[id] => 3
[visitors] => 143
[pageviews] => 617
[created_date] => 2016-03-11
[scount] => 238
)
)
you can test it here: http://www.writephponline.com
Here is your solution:-
$arr1 = $arr1['traffic']; // assign key traffic record to array1
$arr2 = $arr2['source']; // assign key source record to array2
$result = [];
foreach($arr1 as $key=>$value){
$result[$key] = $value;
// find created_date in second array
$keyOfSecondArr = array_search($value['created_date'], array_column($arr2, 'created_date'));
$result[$key]['scount'] = $arr2[$keyOfSecondArr]['scount'];
}
echo '<pre>'; print_r($result);
output:-
Array
(
[0] => Array
(
[id] => 1
[visitors] => 310
[pageviews] => 1333
[created_date] => 2016-03-09
[scount] => 368
)
[1] => Array
(
[id] => 2
[visitors] => 374
[pageviews] => 1010
[created_date] => 2016-03-10
[scount] => 550
)
[2] => Array
(
[id] => 3
[visitors] => 143
[pageviews] => 617
[created_date] => 2016-03-11
[scount] => 238
)
)

Categories