How to sum and count specific keys in a multidimensional array [duplicate] - php

This question already has answers here:
multidimensional array array_sum
(10 answers)
Closed 5 years ago.
I have the following collection that contains the arrays below:
#items: array:2 [▼
0 => array:13 [▼
"label" => "00000000-N/A"
"views" => 980
"clicks" => 444
"form_submissions_perc" => "100.0"
]
1 => array:13 [▼
"label" => "1111-N/A"
"views" => 323
"clicks" => 1009
"form_submissions_perc" => "100.0"
]
]
I am trying to sum clicks and average views but in my try I get the wrong data:
$sum = 0;
foreach ($data as $k => $subArray) {
foreach ($subArray as $id => $value) {
$sum += $subArray['views'];
}
}
dd($sum);
This was my try to sum but didnt get the right results
Desired output
array:2 [
"views"=> 1303,
"clicks"=> 1451
]

Use $sum as array and get correct value of multiarray:
$sum = array(
'clicks' => 0,
'views' => 0
);
foreach ($data as $id => $value) {
$sum['clicks'] += $value['clicks'];
$sum['views'] += $value['views'];
}
dd($sum);

foreach ($data as $k => $subArray) {
$valueSum[] = $subArray['views'];
$clickSum[] = $subArray['clicks'];
}
echo array_sum($valueSum);
echo array_sum($clickSum);
this is also a clean and easy way .

You can use array_reduce instead
$data = array_reduce($array, function ($old, $new) {
return [
"view" => $old["view"] + $new["view"],
"clicks" => $old["clicks"] + $new["clicks"]
];
}, ["view" => 0, "clicks" => 0]);
print '<pre>';
print_r($data);

$data = [
[
"label" => "00000000-N/A",
"views" => 980,
"clicks" => 444,
"form_submissions_perc" => "100.0"
],
[
"label" => "1111-N/A",
"views" => 323,
"clicks" => 1009,
"form_submissions_perc" => "100.0"
]
];
$result['views'] = array_sum( array_column( $data, 'views' ) );
$result['clicks'] = array_sum( array_column( $data, 'clicks' ) );
dd( $result );
This is the easiest way to do your work.
Result:
Array ( [views] => 1303 [clicks] => 1453 )

Related

Merge arrays in multidimensional array based on multiple values

[
0 => [
'qty' => 10
'section' => 'VK7B'
'time_window' => 1
]
1 => [
'qty' => 1
'section' => 'STIC'
'time_window' => 1
]
2 => [
'qty' => 1
'section' => 'STIC'
'time_window' => 1
]
]
I have this multidimensional array where I want to merge the array's if both the section and the time_window are the same, summing the qty for that array. What is an elegant way to do this?
I have tried this ($sections being the multidimensional arry), but this changes the keys and only checks for one value:
$new = []
foreach ($sections as $s) {
if (isset($new[$s['section']])) {
$new[$s['section']]['qty'] += $s['qty'];
$new[$s['section']]['time_window'] = $s['time_window'];
} else {
$new[$s['section']] = $s;
}
}
[
'VK7B' => [
'qty' => 10
'section' => 'VK7B'
'time_window' => 1
]
'STIC' => [
'qty' => 2
'section' => 'STIC'
'time_window' => 1
]
]
As pointed by #RiggsFolly in the comment you are not checking time_window are the same.
You can do it with this code:
$new = []
foreach ($sections as $s) {
// you need to save both values (section and time_window) to check both of them
if (isset($new[$s['section'].$s['time_window']])) {
$new[$s['section'].$s['time_window']]['qty'] += $s['qty'];
$new[$s['section'].$s['time_window']]['time_window'] = $s['time_window'];
} else {
$new[$s['section'].$s['time_window']] = $s;
}
}
// Now $new is an associative array => let's transform it in a normal array
$new = array_values($new);

Getting zero when extracting data from a PHP array in Laravel app

Am working on some set of PHP array. Am trying to loop through each of them and check
the array whose name is equal to Josw Acade. Am using a for loop but I get zero
after extracting the data. I want to store the data in an array.
Array
array:6 [
0 => array:4 [
"id" => 1
"name" => "Josw Acade"
"value" => "Unlimited"
"plan_type" => "Superior"
]
1 => array:4 [
"id" => 2
"name" => "Verbal"
"value" => "true"
"plan_type" => "Superior"
]
2 => array:4 [
"id" => 12
"name" => "Josw Acade"
"value" => "$1,500,00"
"plan_type" => "Classic"
]
3 => array:4 [
"id" => 13
"name" => "Leon"
"value" => "true"
"plan_type" => "Classic"
]
4 => array:4 [
"id" => 14
"name" => "One Time"
"value" => "true"
"plan_type" => "Classic"
]
5 => array:4 [
"id" => 15
"name" => "Deat"
"value" => "$25,000"
"plan_type" => "Classic"
]
6 => array:4 [
"id" => 23
"name" => "Josw Acade"
"value" => "$100,000"
"plan_type" => "Essential"
]
]
Logic
$Inst = [];
for($med = 0; $med < count($array); $med++){
if($med['name'] == "Josw Acade"){
$Inst = $med['value'];
}
}
dd($Inst);
Your variables is not corretly set in the for loop, you are setting $med = 0 and acessing $med as an array.
Use filter, that runs a condition on each element and returns the items that satisfy that condition.
array_filter($array, function ($item) {
return $item['name'] === 'Josw Acade';
});
In general you don't have to make old school arrays anymore, foreach does the same.
$results = [];
foreach($array as $item)
{
if ($item['name'] === 'Josw Acade') {
$results[] = $item['value'];
}
}
You can use array_filter with callback
$filtered = array_filter($array, function($v){ return $v['name'] == 'Josw Acade'})
print_r($filtered);
You are looping through array; so on each iteration to get values; you need to pass index value and you are missing that. You are using $med as index.
Here is code.
$Inst = [];
for($med = 0; $med < count($array); $med++){
if($array[$med]['name'] == "Josw Acade"){
$Inst[] = $array[$med]['value'];
}
}
there is many way to do this but according to me the best way to use array_filer()
array_filter($array, function ($item) {
return $item['name'] === 'Josw Acade';
});

PHP Combine keys from different arrays

I have an array that looks like this
"name" => array:3 [
1 => "Hello"
4 => "Test"
21 => "Test2"
]
"runkm" => array:3 [
1 => "100.00"
4 => "1000.00"
21 => "2000.00"
]
"active" => array:3 [
1 => "1"
4 => "0"
21 => "0"
]
Can i somehow combine the matching keys with a PHP function so that the array would look like this instead
1 => array:3 [
name => "Hello"
runkm => "100.00"
active => "1"
]
4 => array:3 [
name => "Test"
runkm => "1000.00"
active => "0"
]
21 => array:3 [
name => "Test2"
runkm => "2000.00"
active => "0"
]
EDIT: Thanks for all the answers guys. What i was really looking for was a PHP built in function for this, which i probably should have been more clear about.
$newArr=array();
foreach($array1 as $key => $value){
$newArr[$key]=>array(
'name' =>$value[$key];
'runkm' =>$array2[$key];
'active'=>$array3[$key];
);
}
this is how you make a new array and then print the $newArr and check you get what you want or not? Good Luck!
<?php
$resultarr = array();
for($i=0;$i<count($sourcearr['name']);$i++) {
$resultarr[] = array('name'=>$sourcearr['name'][$i], 'runkm'=>$sourcearr['runkm'][$i], 'active'=>$sourcearr['active'][$i]);
}
This works well. And also, doesn't use hard coded keys.
<?php
$arr = [
"name" => [
1 => "Hello",
4 => "Test",
21 => "Test2"
],
"runkm" => [
1 => "100.00",
4 => "1000.00",
21 => "2000.00"
],
"active" => [
1 => "1",
4 => "0",
21 => "0"
]
];
// Pass the array to this function
function extractData($arr){
$newarr = array();
foreach ($arr as $key => $value) {
foreach($value as $k => $v) {
if(!isset($newarr[$k]))
$newarr[$k] = array();
$newarr[$k][$key] = $v;
}
}
return $newarr;
}
print_r(extractData($arr));
?>
I'm not sure if there's a function that does that in PHP but maybe you can try this
$arr1 = array(
"name" => array(
1 => "hello",
4 => "test",
21 => "test2",
),
"runKm" => array(
1 => "100",
4 => "200",
21 => "300",
),
"active" => array(
1 => "1",
4 => "0",
21 => "0",
),
);
// declare another that will hold the new structure of the array
$nArr = array();
foreach($arr1 as $key => $val) {
foreach($val as $sub_key => $sub_val) {
$nArr[$sub_key][$key] = $sub_val;
}
}
what this does is simply loop thru each array and its values and assign it to another array which is the $nArr. I hope it helps.

How to add array if key value is same

Hi i having difficulty to trace an multi dimensional array.
[
0 => array:7 [
"date" => "2016-01-19"
"placement_id" => 1
"requests" => 18
"revenue" => 1
],
1 => array:7 [
"date" => "2016-01-19"
"placement_id" => 1
"requests" => 2
"revenue" => 0.2
]
];
if placement_id are same i want resulted array:
1 => array:7 [
"date" => "2016-01-19"
"placement_id" => 1
"requests" => 20
"revenue" => 1.2
]
The requirement is to produce an output array that has:
Items with the same 'placement_id' having the 'requests' and revenue summed.
The key of the entry in the output array will be be the 'placement_id'.
That means that the output array will be smaller that the input array.
I decided to use the array_reduce function. There is no special reason, foreach loops work fine. It isn't any more efficient. It is just different.
The important point about array_reduce is that the $carry (accumulator) can be an array...
Working example at Eval.in
The code:
$outArray = array();
$outArray = array_reduce($src,
function($carry, $item) { // accumulate values if possible
$carryKey = $item['placement_id']; // array key
if (isset($carry[$carryKey])) { // accumulate values
$carry[$carryKey]['requests'] += $item['requests'];
$carry[$carryKey]['revenue'] += $item['revenue'];
} else { // is new - add to the output...
$carry[$carryKey] = $item;
}
return $carry;
},
array() /* accumulator ($carry) is an internal variable */);
Output Array:
array (2) [
'1' => array (4) [
'date' => string (10) "2016-01-19"
'placement_id' => integer 1
'requests' => integer 20
'revenue' => float 1.2
]
'666' => array (4) [
'date' => string (10) "2016-04-01"
'placement_id' => integer 666
'requests' => integer 266
'revenue' => float 666.20000000000005
]
]
Test Data:
$src = array(
0 => array(
"date" => "2016-01-19",
"placement_id" => 1,
"requests" => 18,
"revenue" => 1,
),
1 => array(
"date" => "2016-04-01",
"placement_id" => 666,
"requests" => 266,
"revenue" => 666.2,
),
2 => array(
"date" => "2016-01-19",
"placement_id" => 1,
"requests" => 2,
"revenue" => 0.2,
),
);
Taking that $arr parameter is the array that you show, we could create a function like this to look for duplicates ids and aggregate them. The $output array will return the results.
public function checkArray($arr) {
$output = array();
$deleted = array();
foreach($arr as $key => $value){
if (!in_array($key, $deleted)) {
$entry = array();
$entry['date'] = $value['date'];
$entry['placement_id'] = $value['placement_id'];
$entry['requests'] = $value['requests'];
$entry['revenue'] = $value['revenue'];
foreach($arr as $key2 => $value2){
if($key != $key2 && $value['placement_id'] == $value2['placement_id']){
$entry['requests'] += $value2['requests'];
$entry['revenue'] += $value2['revenue'];
$deleted[] = $key2;
}
}
$output[] = $entry;
}
}
return $output;
}

Flip associative array and store new values in subarrays to prevent losing duplicated values

I have a flat associative array which may contain duplicate values.
Array (
[for-juniors] => product_category
[for-men] => product_category
[coats] => product_category
[for-women] => product_category
[7-diamonds] => brand
)
I need to restructure the data to store the original values as new keys and the original keys pushed into subarrays associated with the new keys.
array(
'product_category' => array(
'for-juniors',
'for-men',
'coats',
'for-women'
),
'brand' => array(
'7-diamonds'
)
);
$grouped = array();
foreach ($input as $choice => $group) {
$grouped[$group][] = $choice;
}
var_dump($grouped);
Because within a foreach() loop, the values are declared BEFORE the keys, you can actually populate the new data structure with a body-less foreach() loop.
Code: (Demo)
$array = [
'for-juniors' => 'product_category',
'for-men' => 'product_category',
'coats' => 'product_category',
'for-women' => 'product_category',
'7-diamonds' => 'brand'
];
$grouped = [];
foreach ($array as $grouped[$group][] => $group);
var_export($grouped);
Output:
array (
'product_category' =>
array (
0 => 'for-juniors',
1 => 'for-men',
2 => 'coats',
3 => 'for-women',
),
'brand' =>
array (
0 => '7-diamonds',
),
)
This'll do:
function array_flip_safe(array $array) : array
{
return array_reduce(array_keys($array), function ($carry, $key) use (&$array) {
$carry[$array[$key]] ??= []; // PHP 7.0 - ^7.3: $carry[$array[$key]] = $carry[$array[$key]] ?? [];
$carry[$array[$key]][] = $key;
return $carry;
}, []);
}
The callback creates an empty array if the array doesn't already exist. Then it appends current iteration's $key ($value of array_keys($array)) to that array.
Here's an example for better understanding:
$businessHours = [
'mo' => '13:00 - 16:00',
'tu' => '8:00 - 12:00',
'we' => '13:00 - 16:00',
'th' => '8:00 - 12:00',
'fr' => '13:00 - 16:00',
'sa' => '',
'su' => '',
];
$flipped = array_flip_safe($businessHours);
ray($flipped); (or var_dump, var_export, etc.) outputs:
array:3 [▼
"13:00 - 16:00" => array:3 [▼
0 => "mo"
1 => "we"
2 => "fr"
]
"8:00 - 12:00" => array:2 [▼
0 => "tu"
1 => "th"
]
"" => array:2 [▼
0 => "sa"
1 => "su"
]
]
Note that the order of inner arrays' values is the same as the order of original array's keys.

Categories