Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

php array_udiff to compare array values with threshold (tolerance)

I need to compare database values with post values. If post values (decimal price) are within 2 cents threshold consider values equal. Result is array with 'real' difference. Arrays are consistent: same number of values, same keys.

$db_values =   array( "21" => 10.00, "22" => 20.00, "25" => 3.55);
$post_values = array( "21" => 9.98,  "22" => 20.01, "25" => 2.55 ); 

I'm trying to compare Absolute value to my tolerance value -- epsilon (Compare decimals in PHP) and array_udiff:

function epsilon_compare ($v1,$v2)
{
 $epsilon = 0.02;
 $diff = abs($v1 - $v2);

   if ($diff <= $epsilon) 
    { 
            return 0;
      //echo "numbers are equal";
      } else {
         return 1;
             }
    }

 print_r(array_udiff($post_values, $db_values, "epsilon_compare"));

gives correct result: Array ( [25] => 2.55 )

but when i use different array I get wrong result eg:

   $db_values =   array( "21" => 10.00, "22" => 20.00, "25" => 3.55);
   $post_values = array( "21" => 8.00,  "22" => 20.01, "25" => 2.55 );

In this case it gives:

   Array ( [21] => 8 [22] => 20.01 [25] => 2.55 ) 

Key [22] => 20.01 is listed but it is within the threshold so it shouldn't be in result set. I think I don't fully understand array_udiff. thanks.

like image 590
phpJs Avatar asked Nov 25 '22 08:11

phpJs


1 Answers

I don't think that udiff does what you think it does. If you print v1 and v2 it will give you the following:

v1: 20.01 v2: 9.98
v1: 2.55 v2: 20.01
v1: 20 v2: 10
v1: 3.55 v2: 20
v1: 9.98 v2: 10
v1: 9.98 v2: 20.01
v1: 20.01 v2: 20
v1: 20.01 v2: 2.55
v1: 2.55 v2: 3.55 

It makes more comparisons than you think.

You probably need a piece of code that looks something like:

function compare_arrays($array1, $array2){
    $result = array();
    foreach($array1 as $value => $outcome){
        if(epsilon_compare($array1[$value], $array2[$value])){
            $result[$value] = $array2[$value];
        }
    }
    return $result;
}
like image 187
Dennis Avatar answered Nov 27 '22 21:11

Dennis