-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathArrayDiffMultidimensional.php
More file actions
110 lines (98 loc) · 3.28 KB
/
ArrayDiffMultidimensional.php
File metadata and controls
110 lines (98 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
<?php
namespace Rogervila;
class ArrayDiffMultidimensional
{
/**
* Returns an array with the differences between $array1 and $array2
* $strict variable defines if comparison must be strict or not
*
* @param array $array1
* @param mixed $array2
* @param bool $strict
*
* @return array
*/
public static function compare($array1, $array2, $strict = true)
{
if (!is_array($array1)) {
throw new \InvalidArgumentException('$array1 must be an array!');
}
if (!is_array($array2)) {
return $array1;
}
$result = [];
foreach ($array1 as $key => $value) {
// Use isset for better performance, fall back to array_key_exists for null values
if (!isset($array2[$key]) && !array_key_exists($key, $array2)) {
$result[$key] = $value;
continue;
}
$value2 = $array2[$key];
if (is_array($value)) {
if (empty($value)) {
if (!is_array($value2) || !empty($value2)) {
$result[$key] = $value;
}
continue;
}
// Only recurse if both are arrays
if (is_array($value2)) {
$recursiveArrayDiff = static::compare($value, $value2, $strict);
if (!empty($recursiveArrayDiff)) {
$result[$key] = $recursiveArrayDiff;
}
} else {
$result[$key] = $value;
}
continue;
}
// Handle scalar value comparison optimization
if ($strict) {
// Strict comparison - optimize float handling
if (is_float($value) && is_float($value2)) {
// Use epsilon comparison for float precision
$epsilon = defined('PHP_FLOAT_EPSILON') ? PHP_FLOAT_EPSILON : 2.2204460492503E-16;
if (abs($value - $value2) > $epsilon) {
$result[$key] = $value;
}
} elseif ($value !== $value2) {
$result[$key] = $value;
}
} else {
// Loose comparison - convert if either is float
if (is_float($value) || is_float($value2)) {
if ((string) $value != (string) $value2) {
$result[$key] = $value;
}
} elseif ($value != $value2) {
$result[$key] = $value;
}
}
}
return $result;
}
/**
* Returns an array with a strict comparison between $array1 and $array2
*
* @param array $array1
* @param array $array2
*
* @return array
*/
public static function strictComparison($array1, $array2)
{
return static::compare($array1, $array2, true);
}
/**
* Returns an array with a loose comparison between $array1 and $array2
*
* @param array $array1
* @param array $array2
*
* @return array
*/
public static function looseComparison($array1, $array2)
{
return static::compare($array1, $array2, false);
}
}