get the sum and difference of two associate array in php - php

I have 2 arrays.
arr1 =array('cat'=>5,'dog'=>2);
arr2 = array('cat'=>1,'dog'=>2);
I need to get the sum of 2 arrays and the difference of these arrays.
arr3 = array(cat =>6,dog =>4);
arr4 = array(cat =>4 ,dog =>0);
I tried USING array_merge,array_diff,array_combine
But nothing gives me what i need.
plz help

Assuming we have the same number of like keys in both arrays we can iterate through one or the other and find and work with the corresponding values belonging to the other identified by the same named keys.
<?php
$a1 = array('cat'=>5,'dog'=>2);
$a2 = array('cat'=>1,'dog'=>2);
foreach($a1 as $k => $v)
{
$add[$k] = $v + $a2[$k];
$sub[$k] = $v - $a2[$k];
}
var_dump($add, $sub);
Output:
array(2) {
["cat"]=>
int(6)
["dog"]=>
int(4)
}
array(2) {
["cat"]=>
int(4)
["dog"]=>
int(0)
}

You could always resolve the first problem with array_sum.
Second is more interesting, I'd solve it with an array_map. See it in action here
$subtracted = array_map(function ($x, $y) {
return $x - $y;
}, $arr1, $arr2);
$result = array_combine(array_keys($arr1), $subtracted);
Note that you can also solve the first problem by replacing - with + in the above example.
Also note that array_map tends to be generally more readable.

Simple foreach can do it, below example if some key is missing and just getting difference not in -ve Negative sign, the difference would be 4 not -4 for 1 cat - 5 cat
<?php
$arr1 =array('cat'=>5,'dog'=>2);
$arr2 = array('cat'=>1,'dog'=>2);
$sum= [];
$sub= [];
foreach(array_merge($arr1,$arr2) as $k=>$v){
$a1 = $arr1[$k] ?? 0;
$a2 = $arr2[$k] ?? 0;
$sum[$k] = $a1 + $a2;
$sub[$k] = abs($a1 - $a2);
}
print_r($sum);
print_r($sub);
?>
Live Demo
With simple foreach loop
If some data exist only in single array

Related

How to optimize multiple if check for array index check and initialize value 1

I have a string which has "23:22:0"
$string = "23:22:0";
$array = explode(":", $string);
if ($array[0] == 0) {
$array[0] = 1;
}
if ($array[1] == 0) {
$array[1] = 1;
}
if ($array[2] == 0) {
$array[2] = 1;
}
How to avoid multiple if condition check here and i need this condition to be optimised in some best way. Any help is appreciated thanks in advance.
Please check below example. I have commented out your $string variable and tested $string with '0:0:0' value.
Added print_r() to check whether the value is correct or not as we are expecting.
Hope it might be helpful.
//$string = "23:22:0";
$string = "0:0:0";
$array = explode(":", $string);
$array = array(
0 => ($array[0] == 0) ? 1 : $array[0],
1 => ($array[1] == 0) ? 1 : $array[1],
2 => ($array[2] == 0) ? 1 : $array[2],
);
print_r($array);
I wrote this answer because I thought there was an unknown number of items.
OP has now clarified that it's always three items. This is probably a bit overkill for the task at hand.
You can create a new array with 1's and use array_replace to merge it with the original array if you first remove the zero values.
$string = "23:22:0";
$array = explode(":", $string);
$fill = array_fill(0,count($array), 1); //create new array [1,1,1]
$array= array_filter($array); // remove zero values
$array= array_replace($fill,$array); // "merge" the arrays
var_dump($array);
Output:
array(3) {
[0]=>
string(2) "23"
[1]=>
string(2) "22"
[2]=>
int(1)
}
https://3v4l.org/thpfU
With three items in mind you can make the code look better with a loop.
It will perform about the same I believe.
foreach($array as &$val){
if(!$val) $val=1;
}

Foreach only repeats last element of array

$amount = 2;
$array = array(3,6,12);
foreach($array as $a){
$total = $a*$amount;
}
result for only the last element:
int(24) int(12)
result must be:
int(6)
int(12)
int(24)
I want to calculate a sum of all the elements in the array, but only the last element is calculated.
Iterate over each element of the array passed as reference and update inside the loop, like this:
$amount = 2;
$array = array(3,6,12);
foreach($array as &$a){
$a = $a*$amount;
}
var_dump($array);
If you say that you want calculate sum elements of array $amount isn't neccesary.
You can use array_reduce You can see documentation here
function sumArray($carry, $item)
{
$carry += $item;
return $carry;
}
array_reduce($array, "sumArray");
if you need get array with (6,12,24) you can use
function sumArray($item)
{
return $item*2;
}
array_map("sumArray",$array); //array(6,12,24)
If this is indeed your code you should get a lot of undefined errors. You say that you want to get the sum, so why are you multiplying with $amount?
You want to do this:
<?php
$array = array(3,6,12);
$total = 0;
foreach($array as $a){
$total += $a;
}
Or even easier:
Just use array_sum:
array_sum — Calculate the sum of values in an array
Like so:
<?php
$array = array(3,6,12);
echo array_sum($array);
use array_map:
function double($v)
{
return $v * 2;
}
$a=array(3, 6, 12);
$resArr = array_map("double" ,$a));
the result will be an array [6, 12, 24]

PHP array_merge empty values always less prioritar

My goal is to merge 2 different arrays.
I have table "a" & "b".
Data from table "a" are more prioritar.
PROBLEM: if a key from "a" contains an empty value, I would like to take the one from table "b".
Here is my code:
<?php
$a = array('key1'=> "key1 from prioritar", 'my_problem'=> "");
$b = array('key1'=> "key1 from LESS prioritar", 'key2'=>"key2 from LESS prioritar", 'my_problem'=> "I REACHED MY GOAL!");
$merge = array_merge($b, $a);
var_dump($merge);
Is there a way to do this in one function without doing something like below?
foreach($b as $key => $value)
{
if(!array_key_exists($key, $a) || empty($a[$key]) ) {
$a[$key] = $value;
}
}
You can use array_replace and array_filter
$mergedArray = array_replace($b, array_filter($a));
The result would be:
array(3) {
["key1"]=>
string(19) "key1 from prioritar"
["key2"]=>
string(24) "key2 from LESS prioritar"
["my_problem"]=>
string(18) "I REACHED MY GOAL!"
}
Just array_filter() $a which will remove any item with '' value.
$merge = array_merge($b, array_filter($a));

Most efficient way to get keys,values between two keys of an Associative array

i have an array
$var = array("one"=>"one","two"=>"two","three"=>"three","four"=>"four");
if i passed keys one,three i want to get values one , two ,three with keys .
now i am doing is
$new_array = array_diff(array_slice($var,$key1),array_slice($var,$key2));
$new_array[$key1] = $var[$key1];
$new_array[$key2] = $var[$key2];
is there any efficient way , please help .
You pass in a key $from and a key $to. To have something from - to working, you need to know the order as well. You get the order of keys with array_keys:
$keys = array_flip(array_keys($array));
Now you can locate both the offset of $from and $to keys:
array_slice($array, $keys[$from], $keys[$to] - $keys[$from] + 1);
Compile as a full example:
<?php
/**
* Most efficient way to get keys,values between two keys of an Associative array
* #link http://stackoverflow.com/q/11358192/367456
*/
$array = array("one" => "one", "two" => "two", "three" => "three", "four" => "four");
$slice = function($from, $to) use ($array)
{
$keys = array_flip(array_keys($array));
if (isset($keys[$from]) and isset($keys[$to])) {
return array_slice($array, $keys[$from], $keys[$to] - $keys[$from] + 1);
}
throw new InvalidArgumentException('Invalid from and/or to key.');
};
var_dump($slice('one', 'three'));
Output:
array(3) {
["one"]=>
string(3) "one"
["two"]=>
string(3) "two"
["three"]=>
string(5) "three"
}
Assuming your input array has contiguous keys, why not just:
$newArray = array_slice($array, $key1, $key2 + 1);
EDIT
Oh wait, that will only work when $key1 = 0, try this instead:
$newArray = array_slice($array, $key1, ($key2 - $key1) + 1);
This still requires that $key1 < $key2, but from what you say I imagine it always will be.
ANOTHER EDIT
In order to accomplish this without looping the array (with would of course be the easiest way) you need to convert the string keys to numerics so they can be used with array_slice(). This works:
$var = array("one"=>"one","two"=>"two","three"=>"three","four"=>"four");
$key1 = 'one';
$key2 = 'three';
$keys = array_keys($var);
$key1index = array_search($key1, $keys);
$key2index = array_search($key2, $keys);
$newArray = array_slice($var, $key1index, ($key2index - $key1index) + 1, TRUE);
print_r($newArray);

(PHP) Checking items in an array

I have an array like this:
Array(a,b,c,a,b)
Now, if I would like to check how many instances of "b" I can find in the array, how would I proceed?
See the documentation for array_count_values(). It seems to be what you are looking for.
$array = array('a', 'b', 'c', 'a', 'b');
$counts = array_count_values($array);
printf("Number of 'b's: %d\n", $counts['b']);
var_dump($counts);
Output:
Number of 'b's: 2
array(3) {
["a"]=> int(2)
["b"]=> int(2)
["c"]=> int(1)
}
Use array_count_values($arr). This returns an associative array with each value in $arr as a key and that value's frequency in $arr as the value. Example:
$arr = array(1, 2, 3, 4, 2);
$counts = array_count_values($arr);
$count_of_2 = $counts[2];
You can count the number of instances by using this function..
$b = array(a,b,c,a,b);
function count_repeat($subj, $array) {
for($i=0;$i<count($array);$i++) {
if($array[$i] == $subj) {
$same[] = $array[$i]; //what this line does is put the same characters in the $same[] array.
}
return count($same);
}
echo count_repeat('b', $b); // will return the value 2
Although there are some fancy ways, a programmer should be able to solve this problem using very basic programming operators.
It is absolutely necessary to know how to use loops and conditions.
$count = 0;
$letters= array("a","b","c","a","b");
foreach ($letters as $char){
if ($char == "b") $count = $count+1;
}
echo $count.' "b" found';
NOT a rocket science.

Categories