gotchaphpMinor
Calculating the difference between 2 arrays
Viewed 0 times
thearraysdifferencecalculatingbetween
Problem
I made this function to calculate the difference between 2 arrays and return it in a third array. I'm using this function as a part of stocktaking functionality I apply in my accounting system.
Case example
When the user do the stocktaking, its result are going to be saved in
This is a stocktaking result example:
I then compare it against the stock quantities according to the data in the system
I made this function to do that job. I need it to tell me the changes that happened for every product between the data in the system and the actual data come from the stocktaking, for example, let's take product_id
In the system it was
The function also needs to consider about these points:
function stockdiff ($array2,$array1){
//inputs :
//$array2 is the stocktaking result in an array that has the format "$product_id=>$quantity"
//$array1 is the stock according to the data in the system in an array that has the format "$product_id=>$quantity"
foreach($array2 as $key=> $value){
if(isset($array1[$key])){$result[$key] = $array2[$key] - $array1[$key];}
else{$result[$key] = $array2[$key];}
}
$array1diff = array_diff_key($array1,$array2);
foreach($array1diff as $key=> $value){
$result[$key] = -1 * $array1[$key];
}
return $result;
}Case example
When the user do the stocktaking, its result are going to be saved in
$array2 in the format $product_id=>$quantity.This is a stocktaking result example:
$array2[2] = 500;
$array2[3] = 7;
$array2[1] = 302;
$array2[105] = 7000;
$array2[7] = 304;
$array2[8] = 20;
$array2[9] = 20;
$array2[11] = 20;
$array2[73] = 32;
$array2[21] = 35;I then compare it against the stock quantities according to the data in the system
$array1 which might be something like this:$array1[1] = 30;
$array1[2] = 60;
$array1[3] = 202;
$array1[4] = 200;
$array1[7] = 0;
$array1[8] = 0;
$array1[9] = 0;
$array1[11] = 52;
$array1[21] = 70;
$array1[99] = 21;I made this function to do that job. I need it to tell me the changes that happened for every product between the data in the system and the actual data come from the stocktaking, for example, let's take product_id
2.In the system it was
$array1[2] = 60; 60 units from the product 2, and the stocktaking told us no, we found 500 units from the product 2 $array2[2] = 500;. So, the function must return [2]=>440.The function also needs to consider about these points:
- If there is a product in the stockta
Solution
Regarding the way to achieve this task I couldn't find any better strategy than yours.
On the other hand your code may be made cleaner and more readable by:
It results in a reduced code:
NOTE: regarding the use of
I don't agree with this too general point of view: sure it must be avoided in many situations where it might lead to some issues, but it's pretty legal when used carefully and with discernment.
In the case above, the only "error" it may hide is the one we know it may happen (undefined index), so it keeps sure.
And so it helps making the code more readable and reduced:
is replaced by
The only con is about performance: using
On the other hand your code may be made cleaner and more readable by:
- first merely following best-practices (don't put several statements in the same line,
- using more significant names (such as
$initialand$finalinstead of$array1and$array2,$final_valueand$initial_valuerather than only$value)
- avoiding to declare useless variables (like
$array1diff, used only once)
- using the more direct expressions when possible (e.g.
$array2[key]is already available as$value, while-1 * $array1[$key]is merely-$array1[$key])
- using the ternary operator where it can simplify the code (see also the note below)
It results in a reduced code:
function stock_diff($initial, $final) {
foreach ($final as $key => $final_value) {
$result[$key] = $final_value - @$initial[$key] ?: 0;
}
foreach(array_diff_key($initial, $final) as $key => $initial_value) {
$result[$key] = -$initial_value;
}
return $result;
}NOTE: regarding the use of
@ in the ternary operator, I know that many people automatically banish it as globally evil.I don't agree with this too general point of view: sure it must be avoided in many situations where it might lead to some issues, but it's pretty legal when used carefully and with discernment.
In the case above, the only "error" it may hide is the one we know it may happen (undefined index), so it keeps sure.
And so it helps making the code more readable and reduced:
(isset($initial[$key]) ? $initial[$key] : 0)is replaced by
@$initial[$key] ?: 0The only con is about performance: using
@ works slightly slower than isset(). So avoid it when you know that a piece of code will be executed a significantly huge number of times.Code Snippets
function stock_diff($initial, $final) {
foreach ($final as $key => $final_value) {
$result[$key] = $final_value - @$initial[$key] ?: 0;
}
foreach(array_diff_key($initial, $final) as $key => $initial_value) {
$result[$key] = -$initial_value;
}
return $result;
}Context
StackExchange Code Review Q#147251, answer score: 3
Revisions (0)
No revisions yet.