PHP calculate array data - php

I am having trouble to calculate the sum of an array values
my array is
$bar_chart_data =
array(
array(
array("Data1",548.25),
array("Data2",238.75),
array("Data3",95.50),
array("Data4",300.50),
array("Data5",286.80),
array("Data6",148.25)
)
);
I am using this php code to calculate the results but its always gives me 0
$sumArray = array();
foreach ($bar_chart_data as $k=>$subArray) {
foreach ($subArray as $id=>$value) {
$sumArray[$id]+=$value;
}
}
print_r($sumArray);

Your $id is different in all iteration.
You have to use $sumArray[$k]+=$value[1];.
You also have to init $sumArray[$k] to 0 between your two foreach.

I believe you have an array containing a sub-array and you want to get the sum of all the values in each of the sub-arrays.
I suggest you use an associative sub-array to make the task easier.
$bar_chart_data = array(
array(
"Data1" => 548.25,
"Data2" => 238.75,
"Data3" => 95.50,
"Data4" => 300.50,
"Data5" => 286.80,
"Data6" => 148.25
),
array(
)
);
$sumArray = array(); // Create an empty array to store the sum of each sub-array
foreach ($bar_chart_data as $subArray) {
$sum = 0; // Initialize sum as zero
foreach ($subArray as $key=>$value) {
$sum += $value;
}
$sumArray[] = $sum; // Append each sum to the array
}
print_r($sumArray); // Print the array containing the sums.

You only need one loop, then extract the values at index 1 and sum them:
foreach($bar_chart_data as $values) {
$sumArray[] = array_sum(array_column($values, 1));
}
You can add the $k => $values back and use $sumArray[$k] if needed, but the way your array is shown it will work without it.

Related

php, sum two array values

I have two array
first array:
Array (
[01-1970] => 0.00
[03-2019] => 4350.00
[05-2019] => 150.00
[06-2019] => 50.00
)
second array:
Array (
[03-2019] => 0.00
[04-2019] => 0.00
[06-2019] => 34.83
)
My expected sum result is:
Array (
[01-1970] => 0.00
[03-2019] => 4350
[04-2019] => 0.00
[05-2019] => 150.00
[06-2019] => 84.83
)
How can achieve this?
You can use array_keys to get the unique from both of the array and then loop through keys to some them
$r = [];
$keys = array_keys($a1+$a2);
foreach($keys as $v){
$r[$v] = (empty($a1[$v]) ? 0 : $a1[$v]) + (empty($a2[$v]) ? 0 : $a2[$v]);
}
Working DEMO
Your best bet is to loop the arrays individually, and sum up the values into a resulting array as you go. We can create a new array that contains the two arrays them to shorten our code a bit (see how we define [$first, $second] as the first loop).
This removes any problems with mixed lengths, and keeps all the keys and values in the array intact.
$result = [];
// Loop over our two arrays, here called $first and $second
foreach ([$first, $second] as $a) {
// Loop over the values in each array
foreach ($a as $k=>$v) {
// If the index is new to the $result array, define it to be zero (to avoid undefined index notices)
if (!isset($result[$k]))
$result[$k] = 0;
// Sum up the value!
$result[$k] += $v;
}
}
print_r($result);
Live demo at https://3v4l.org/X4ijP
You can make use of a function I made:
<?php
function array_sum_multi($arrayOne, $arrayTwo)
{
# get rid of keys
$valuesOne = array_values($arrayOne);
$valuesTwo = array_values($arrayTwo);
//create return array
$output = [];
# loop that shizzle
for ($i = 0; $i < count($valuesOne); $i++)
{
$output[$i] = $valuesOne[$i] + (!empty($valuesTwo[$i]) ? $valuesTwo[$i] : 0);
}
return $output;
}
$result = array_sum_multi([0.00, 4350.00, 150.00, 50.00], [0.00, 0.00, 34.83]);
# then for your keys:
$result = array_combine(array_keys($yourFirstArray), $result);
echo '<pre>'. print_r($result, 1) .'</pre>';
$result = $first_array; // just copy array into result
// scan second array
foreach ($second_array as $k => $v) {
// if key already exists, then add, else just set
$result[$k] = isset($result[$k]) ? ($result[$k] + $v) : $v;
}
// done
print_r($result);
An easy way to implement it would be to loop through each array, and add it to a common array with the same key.
Looping through only one array would result in a lack of a few elements if the first array is smaller than the second one or if some element from the second array are not present in the first one.
So let's just loop through both of them and add it to sum.
$sum = [];
foreach($firstArray as $key => $value){
$sum[$key] = $value + (isset($sum[$key]) ? $sum[$key] : 0.0);
}
foreach($secondArray as $key => $value){
$sum[$key] = $value + (isset($sum[$key]) ? $sum[$key] : 0.0);
}
print_r($sum);
Try this simple method thank you,
$sum = [];
foreach($firstArray as $key => $value){
if(array_key_exists($key,$secondArray)){
$newArray = [$key=>$value+$secondArray[$key]];
$sum = array_merge($sum,$newArray);
}else{
$newArray = [$key=>$value];
$sum = array_merge($sum,$newArray);
}
}
//your final required result
var_dump($sum);
Try this,
$a1 = array (
'01-1970' => 0.00,
'03-2019' => 4350.00,
'05-2019' => 150.00,
'06-2019' => 50.00
);
$a2 = array (
'03-2019' => 0.00,
'04-2019' => 0.00,
'06-2019' => 34.83
);
$sums = array();
foreach (array_keys($a1 + $a2) as $key) {
$sums[$key] = #($a1[$key] + $a2[$key]);
}
echo "<pre>";
print_r($sums);
Here is some other solution you can use.
Cheer!
$sumArray = [];
foreach($firstArray as $key => $value) {
$sumArray[$key] = $value + ($secondArray[$key] ?? 0);
}

Group subarrays by one column, make comma-separated values from other column within groups

I have a array that looks like this:
$array = [
["444", "0081"],
["449", "0081"],
["451", "0081"],
["455", "2100"],
["469", "2100"]
];
I need to group as a new array that looks like:
array (
0 =>
array (
0 => '444,449,451',
1 => '0081',
),
1 =>
array (
0 => '455,469',
1 => '2100',
),
)
I'd tried many scripts, but with no success.
function _group_by($array, $key) {
$return = array();
foreach($array as $val) {
$return[$val[$key]][] = $val;
}
return $return;
}
$newArray = _group_by($array, 1); // (NO SUCCESS)
There should be more elegant solutions, but simplest one I can think of would be this.
// The data you have pasted in the question
$data = [];
$groups = [];
// Go through the entire array $data
foreach($data as $item){
// If the key doesn't exist in the new array yet, add it
if(!array_key_exists($item[1], $groups)){
$groups[$item[1]] = [];
}
// Add the value to the array
$groups[$item[1]][] = $item[0];
}
// Create an array for the data with the structure you requested
$structured = [];
foreach($groups as $group => $values){
// With the array built in the last loop, implode it with a comma
// Also add the 'key' from the last array to it ($group)
$structured[] = [implode(',', $values), $group];
}
I haven't tested this but something similar should do the trick. This simply goes through the given array and collects all entries in a structurized manner (so $groups variable will contain an array entry for each group sharing a key, and the key will correspond to the 2nd item in each item within the given array). From there it's just about restructuring it to get the format you have requested.
http://php.net/manual/en/control-structures.foreach.php
Writing two loops is too much effort for this task. Use isset() with temporary keys applied to your output array as you iterate. When finished grouping the data, reindex the output with array_values().
Code (Demo)
$array = [
["444", "0081"],
["449", "0081"],
["451", "0081"],
["455", "2100"],
["469", "2100"]
];
foreach ($array as $row) {
if (!isset($result[$row[1]])) {
$result[$row[1]] = $row; // first occurrence of group, save whole row
} else {
$result[$row[1]][0] .= ',' . $row[0]; // not first occurrence, concat first element in group
}
}
var_export(array_values($result));
Or avoid the temporary associative arrays in the result array by using an array of references. (Demo)
$result = [];
foreach ($array as $row) {
if (!isset($ref[$row[1]])) {
$ref[$row[1]] = $row;
$result[] = &$ref[$row[1]];
} else {
$ref[$row[1]][0] .= ',' . $row[0];
}
}
var_export($result);
Or use array_reduce() to enjoy a functional-style technique. (Demo)
var_export(
array_values(
array_reduce(
$array,
function($result, $row) {
if (!isset($result[$row[1]])) {
$result[$row[1]] = $row;
} else {
$result[$row[1]][0] .= ',' . $row[0];
}
return $result;
}
)
)
);
All will output:
array (
0 =>
array (
0 => '444,449,451',
1 => '0081',
),
1 =>
array (
0 => '455,469',
1 => '2100',
),
)

Loop through a multi dimensional array checking a specific key for repeat values in PHP

I have a multi dimensional array that I have got from a database and I want to check this array for duplicate data and store it in another array of duplicates. my code is as follows
//create temp array
$tmp = array();
foreach ($matchingarray as $nameKey => $match) {
// loop through and stoe the contents of that array to another so i can compare
$tmp[] = $match;
}
// create an array to store duplicates
$duplicatesArray = array();
// if the temp array is not empty then loop through both arrays
if (! empty($tmp)) {
foreach ($tmp as $key => $tmpvalue) {
foreach ($matchingarray as $key => $match) {
// if a key name is the same in both arrays then add it tothe duplicates array
if ($tmpvalue['name'] == $match['name']) {
$duplicatesArray = $match;
}
}
}
}
//count how many are duplicates
$dups = count($duplicatesArray);
What I would like to know is this the right logic?
I will take where Igoel left off
there is 1 error and also 1 suggest that i will make.
Error:
you cannot reuse $key twice in the foreach because they will override.
Suggestion as what Igoel stated: your best bet for duplicate effectively is to use sql. SQL is faster at processing than looping through arrays. Don't forget you need to load the data into memory and thats costly.
Try this way
<?php
static $cnt = array();
$min = 1;
$coll = array(
'dep1' => array(
'fy' => array('john', 'johnny', 'victor'),
'sy' => array('david', 'arthur'),
'ty' => array('sam', 'joe', 'victor')
),
'dep2' => array(
'fy' => array('natalie', 'linda', 'molly'),
'sy' => array('katie', 'helen', 'sam', 'ravi', 'vipul'),
'ty' => array('sharon', 'julia', 'maddy')
)
);
function recursive_search(&$v, $k){
global $cnt;
$cnt[] = $v;
}
array_walk_recursive($coll, 'recursive_search');
$newNumbers = array_filter(
array_count_values($cnt),
function ($value) use($min) {
return ($value > $min);
}
);
echo "Values > 1 are repeated \n";
print_r(array_count_values($cnt));
echo "Values repeted\n";
print_r($newNumbers);
DEMO

Joining rows from two 2d arrays where a common column value is found

I have two arrays that I would like to join into one. Both arrays have a common key=>value and I would like to insert the values of one array to the other so that I to create one array.
$array1 = [
['ID' => 123456, 'Key' => 1000, 'value' => 123.45],
['ID' => 789012, 'Key' => 1001, 'value' => 56748.17],
];
$array2 = [
['Key' => 1000, 'description' => 'desc1'],
['Key' => 1001, 'description' => 'desc2'],
];
I would like to join Array2 with Array1 so that the resulting Array is as follows:
array (
0 =>
array (
'ID' => 123456,
'Key' => 1000,
'value' => 123.45,
'description' => 'desc1',
),
1 =>
array (
'ID' => 789012,
'Key' => 1001,
'value' => 56748.17,
'description' => 'desc2',
),
)
So the arrays have been joined using the [Key] value as the, well, key. I've looked at array_merge and other function but I can't seem to get these two arrays to "merge" properly.
try this, its linear
$keyval = array();
foreach($array1 as $item)$keyval[$item['Key']] = $item['value'];
foreach($array2 as $key=>$item)$array2[$key]['description'] = isset($keyval[$item['Key']]) ? $keyval[$item['Key']] : '';
You would have to do something like
$result = array();
foreach ($a1 as $v1)
{
foreach ($a2 as $k2 => $v2)
{
if ($v1['Key'] === $v2['Key'])
{
$result[] = array_merge($v1, $v2);
unset($a2[$k2]);
break;
}
}
}
Version with for loops
$result = array();
$c_a1 = count($a1);
$c_a2 = count($a2);
for ($i = 0; $i < $c_a1; $i++)
{
for ($j = 0; $j < $c_a2; $j++)
{
if ($a1[$i]['Key'] === $a2[$j]['Key'])
{
$result[] = array_merge($a1[$i], $a2[$j]);
unset($a2[$j]);
$c_a2--;
break;
}
}
}
This is my approach:
$temp_ array = array_fill_keys (array_map(create_function('$a', 'return $a["Key"];'), $array_1) , $array_1);
$result = array();
foreach ($array_2 as $item) {
if (isset($temp_array[$item['Key']])) {
$result[] = array_merge($item, $temp_array[$item['Key']]);
}
}
I have elaborated more in the code above, and reached this improved version:
function array_merge_items_by_common_key_value($key, $array_1, $array_2)
{
$result = array();
$temp_ array = array_fill_keys(array_map(create_function('$a', 'return $a["' . $key . '"];'), $array_1) , $array_1);
foreach ($array_2 as $item)
{
$result[$item[$key]] = isset($temp_array[$item[$key]]) ? array_merge($item, $temp_array[$item[$key]]) : $item;
}
return array_values(array_merge($result, array_diff_key($array_1, $result)));
}
$merged_arrays = array_merge_items_by_common_key_value('Key', $temp_array, $array_2);
First, a temporary array is created: it is equal to $array_1, but its keys are the values to be matched.
Then, $array_2 is looped. When a match is found, the merge is done. If there is no match, then the $array_2 value is maintained, untouched.
Finally, those values in the $array_1 which were not matched, are also appended to the resulting array.
So, no item of both $array_1 or $array_2 is lost, while the matched items are merged.
#radashk's solution will work if you can always guarantee that $array1[$i] corresponds to $array2[$i]. From my reading of the question, that's not guaranteed, but instead you want to make sure that $array1[$i]['Key'] == $array2[$j]['Key'], and combine elements where those Keys match.
There may be a more elegant solution, but I would do it like this:
// builds up new $tmpArray, using the Key as the index
$tmpArray = array();
foreach($array1 as $innerArray1){
$tmpArray[$innerArray1['Key']] = $innerArray1;
}
//Merges the values from $array2 into $tmpArray
foreach($array2 as $innerArray2) {
if (isset($tmpArray[$innerArray2['Key']])) {
$tmpArray[$innerArray2['Key']] = array_merge($tmpArray[$innerArray2['Key']], $innerArray2);
}else{
$tmpArray[$innerArray2['Key']] = $innerArray2;
}
}
Use temporary first level keys to swiftly identify matching Key values between the two arrays. When an array2 row qualifies for merger with the first, use the union-assignment operator (+=). Call array_value() after looping if you don't want to preserve the temporary keys.
Code: (Demo)
$result = array_column($array1, null, 'Key');
foreach ($array2 as $row) {
if (isset($result[$row['Key']])) {
$result[$row['Key']] += $row;
}
}
var_export(array_values($result));

PHP array unset string

I am trying to unset a group of array keys that have the same prefix. I can't seem to get this to work.
foreach ($array as $key => $value) {
unset($array['prefix_' . $key]);
}
How can I get unset to see ['prefix_' . $key] as the actual variable? Thanks
UPDATE: The $array keys will have two keys with the same name. Just one will have the prefix and there are about 5 keys with prefixed keys:
Array {
[name] => name
[prefix_name] => other name
}
I don't want to remove [name] just [prefix_name] from the array.
This works:
$array = array(
'aa' => 'other value aa',
'prefix_aa' => 'value aa',
'bb' => 'other value bb',
'prefix_bb' => 'value bb'
);
$prefix = 'prefix_';
foreach ($array as $key => $value) {
if (substr($key, 0, strlen($prefix)) == $prefix) {
unset($array[$key]);
}
}
If you copy/paste this code at a site like http://writecodeonline.com/php/, you can see for yourself that it works.
You can't use a foreach because it's only a copy of the collection. You'd need to use a for or grab the keys separately and separate your processing from the array you want to manipulate. Something like:
foreach (array_keys($array) as $keyName){
if (strncmp($keyName,'prefix_',7) === 0){
unset($array[$keyName]);
}
}
You're also already iterating over the collection getting every key. Unless you had:
$array = array(
'foo' => 1,
'prefix_foo' => 1
);
(Where every key also has a matching key with "prefix_" in front of it) you'll run in to trouble.
I'm not sure I understand your question, but if you are trying to unset all the keys with a specific prefix, you can iterate through the array and just unset the ones that match the prefix.
Something like:
<?php
foreach ($array as $key => $value) { // loop through keys
if (preg_match('/^prefix_/', $key)) { // if the key stars with 'prefix_'
unset($array[$key]); // unset it
}
}
You're looping over the array keys already, so if you've got
$array = (
'prefix_a' => 'b',
'prefix_c' => 'd'
etc...
)
Then $keys will be prefix_a, prefix_c, etc... What you're doing is generating an entirely NEW key, which'd be prefix_prefix_a, prefix_prefix_c, etc...
Unless you're doing something more complicated, you could just replace the whole loop with
$array = array();
I believe this should work:
foreach ($array as $key => $value) {
unset($array['prefix_' . str_replace('prefix_', '', $key]);
}

Categories