我想检查两个数组是否相等。我的意思是:相同的大小、相同的索引、相同的值。我怎样才能做到这一点?
按照用户的建议使用 !==
,如果数组中至少有一个元素不同,我希望以下内容会打印 enter,但实际上并非如此。
if (($_POST['atlOriginal'] !== $oldAtlPosition)
or ($_POST['atl'] !== $aext)
or ($_POST['sidesOriginal'] !== $oldSidePosition)
or ($_POST['sidesOriginal'] !== $sideext)) {
echo "enter";
}
=
太多,应该是 !==
或 !=
['a'] == [0]
是 true
。好吧,这只是 PHP。
$arraysAreEqual = ($a == $b); // TRUE if $a and $b have the same key/value pairs.
$arraysAreEqual = ($a === $b); // TRUE if $a and $b have the same key/value pairs in the same order and of the same types.
请参阅Array Operators。
编辑
不等式运算符为 !=
而非恒等运算符为 !==
以匹配等式运算符 ==
和恒等运算符 ===
。
根据this page。
注意:接受的答案适用于关联数组,但它不会按预期使用索引数组(解释如下)。如果您想比较其中任何一个,请使用此解决方案。此外,此函数可能不适用于多维数组(由于 array_diff 函数的性质)。
使用 $a == $b
或 $a === $b
测试两个索引数组(其中元素的顺序不同)失败,例如:
<?php
(array("x","y") == array("y","x")) === false;
?>
那是因为上面的意思是:
array(0 => "x", 1 => "y")
与 array(0 => "y", 1 => "x")
。
要解决该问题,请使用:
<?php
function array_equal($a, $b) {
return (
is_array($a)
&& is_array($b)
&& count($a) == count($b)
&& array_diff($a, $b) === array_diff($b, $a)
);
}
?>
添加了比较数组大小(由 super_ton 建议),因为它可以提高速度。
array_diff
之前可以加快比较速度。我会添加它。谢谢
$a = [1, 2, 2]; $b = [2, 1, 1];
进行了测试,它返回了 true
,但是这两个数组显然不一样。
尝试序列化。这也将检查嵌套子数组。
$foo =serialize($array_foo);
$bar =serialize($array_bar);
if ($foo == $bar) echo "Foo and bar are equal";
即使使用以不同顺序给出键的数组也适用的简短解决方案:
public static function arrays_are_equal($array1, $array2)
{
array_multisort($array1);
array_multisort($array2);
return ( serialize($array1) === serialize($array2) );
}
将它们与其他值进行比较:
if($array_a == $array_b) {
//they are the same
}
您可以在此处阅读所有数组运算符:http://php.net/manual/en/language.operators.array.php 请注意,例如 ===
还检查数组中元素的类型和顺序是否相同。
===
,具体取决于所需的行为。
function compareIsEqualArray(array $array1,array $array2):bool
{
return (array_diff($array1,$array2)==[] && array_diff($array2,$array1)==[]);
}
!===
不起作用,因为它是语法错误。正确的方法是 !==
(不是三个“等于”符号)
if (array_diff($a,$b) == array_diff($b,$a)) {
// Equals
}
if (array_diff($a,$b) != array_diff($b,$a)) {
// Not Equals
}
从我的观点来看,使用 array_diff 比使用 array_intersect 更好,因为通过这种性质的检查,通常返回的差异小于相似性,这样 bool 转换就不会占用太多内存。
编辑请注意,此解决方案适用于普通数组,并补充了上面发布的 == 和 === 仅对字典有效。
另一种检查相等而不考虑值顺序的方法是使用 http://php.net/manual/en/function.array-intersect.php,如下所示:
$array1 = array(2,5,3);
$array2 = array(5,2,3);
if($array1 === array_intersect($array1, $array2) && $array2 === array_intersect($array2, $array1)) {
echo 'Equal';
} else {
echo 'Not equal';
}
以下版本也适用于使用 http://php.net/manual/en/function.array-uintersect.php 的多维数组:
$array1 = array(
array(5, 2),
array(3, 6),
array(2, 9, 4)
);
$array2 = array(
array(3, 6),
array(2, 9, 4),
array(5, 2)
);
if($array1 === array_uintersect($array1, $array2, 'compare') && $array2 === array_uintersect($array2, $array1, 'compare')) {
echo 'Equal';
} else {
echo 'Not equal';
}
function compare($v1, $v2) {
if ($v1===$v2) {
return 0;
}
if ($v1 > $v2) return 1;
return -1;
}
一种方法:(为 https://www.rfc-editor.org/rfc/rfc6902#section-4.6 实现“认为相等”)
这种方式允许其成员排序不同的关联数组 - 例如,它们在每种语言中都被认为是平等的,但 php :)
// recursive ksort
function rksort($a) {
if (!is_array($a)) {
return $a;
}
foreach (array_keys($a) as $key) {
$a[$key] = ksort($a[$key]);
}
// SORT_STRING seems required, as otherwise
// numeric indices (e.g. "0") aren't sorted.
ksort($a, SORT_STRING);
return $a;
}
// Per https://www.rfc-editor.org/rfc/rfc6902#section-4.6
function considered_equal($a1, $a2) {
return json_encode(rksort($a1)) === json_encode(rksort($a2));
}
$a[$key] = rksort($a[$key]);
array_diff — 计算数组的差异
http://php.net/manual/en/function.array-diff.php
array array_diff ( array $array1 , array $array2 [, array $... ] ) 将 array1 与一个或多个其他数组进行比较,并返回 array1 中不存在于任何其他数组中的值。
array_diff
不能告诉你。试试 array_diff([1, 2], [1, 2, 'hello'])
。
数组上的语法问题
$array1 = array(
'a' => 'value1',
'b' => 'value2',
'c' => 'value3',
);
$array2 = array(
'a' => 'value1',
'b' => 'value2',
'c' => 'value3',
);
$diff = array_diff($array1, $array2);
var_dump($diff);
这是如何与数组进行比较并获得它们之间不同之处的示例。
$array1 = ['1' => 'XXX', 'second' => [
'a' => ['test' => '2'],
'b' => 'test'
], 'b' => ['no test']];
$array2 = [
'1' => 'XX',
'second' => [
'a' => ['test' => '5', 'z' => 5],
'b' => 'test'
],
'test'
];
function compareArrayValues($arrayOne, $arrayTwo, &$diff = [], $reversed = false)
{
foreach ($arrayOne as $key => $val) {
if (!isset($arrayTwo[$key])) {
$diff[$key] = 'MISSING IN ' . ($reversed ? 'FIRST' : 'SECOND');
} else if (is_array($val) && (json_encode($arrayOne[$key]) !== json_encode($arrayTwo[$key]))) {
compareArrayValues($arrayOne[$key], $arrayTwo[$key], $diff[$key], $reversed);
} else if ($arrayOne[$key] !== $arrayTwo[$key]) {
$diff[$key] = 'DIFFERENT';
}
}
}
$diff = [];
$diffSecond = [];
compareArrayValues($array1, $array2, $diff);
compareArrayValues($array2, $array1, $diffSecond, true);
print_r($diff);
print_r($diffSecond);
print_r(array_merge($diff, $diffSecond));
结果:
Array
(
[0] => DIFFERENT
[second] => Array
(
[a] => Array
(
[test] => DIFFERENT
[z] => MISSING IN FIRST
)
)
[b] => MISSING IN SECOND
[1] => DIFFERENT
[2] => MISSING IN FIRST
)
如果要检查非关联数组,解决方案如下:
$a = ['blog', 'company'];
$b = ['company', 'blog'];
(count(array_unique(array_merge($a, $b))) === count($a)) ? 'Equals' : 'Not Equals';
// Equals
$a = array('a', 'b', 'c', 'd');
$b = array('a', 'c', 'b');
echo (count(array_unique(array_merge($a, $b))) === count($a)) ? 'Equals' : 'Not Equals';
以下解决方案适用于您可以作为回调传递的自定义相等函数。请注意,它不检查数组顺序。
trait AssertTrait
{
/**
* Determine if two arrays have the same elements, possibly in different orders. Elements comparison function must be passed as argument.
*
* @param array<mixed> $expected
* @param array<mixed> $actual
*
* @throws InvalidArgumentException
*/
public static function assertArraysContainSameElements(array $expected, array $actual, callable $comparisonFunction): void
{
Assert::assertEquals(\count($expected), \count($actual));
self::assertEveryElementOfArrayIsInAnotherArrayTheSameAmountOfTimes($expected, $actual, $comparisonFunction);
self::assertEveryElementOfArrayIsInAnotherArrayTheSameAmountOfTimes($actual, $expected, $comparisonFunction);
}
/**
* @param array<mixed> $needles
* @param array<mixed> $haystack
*
* @throws InvalidArgumentException
*/
private static function assertEveryElementOfArrayIsInAnotherArrayTheSameAmountOfTimes(
array $needles,
array $haystack,
callable $comparisonFunction
): void {
Assert::assertLessThanOrEqual(\count($needles), \count($haystack));
foreach ($needles as $expectedElement) {
$matchesOfExpectedElementInExpected = \array_filter(
$needles,
static fn($element): bool => $comparisonFunction($expectedElement, $element),
);
$matchesOfExpectedElementInActual = \array_filter(
$haystack,
static fn($element): bool => $comparisonFunction($expectedElement, $element),
);
Assert::assertEquals(\count($matchesOfExpectedElementInExpected), \count($matchesOfExpectedElementInActual));
}
}
}
当我想确保返回预期的元素但我不关心排序时,我通常在数据库集成测试中使用它。
比较两个数组是否相等的正确方法是使用严格相等(===),它以递归方式进行比较。现有答案无法对任意数组(任意深度和顺序的数组,包含顺序数组和关联数组的混合)进行递归排序,因此无法处理任意数组的比较。顺序数组是具有顺序键 (0,1,2,3...) 的关联数组,而关联数组没有顺序键。
要对这些任意数组进行排序,我们必须:
向下遍历到没有更多子数组的叶节点 通过序列化对顺序数组进行排序,然后对其进行排序(以消除必须使用自定义比较器的需要) 按键对关联数组进行排序
以下代码实现了上述解决方案。欢迎对代码进行改进。
function recur_sort( &$array ) {
foreach ( $array as &$value ) {
if ( is_array( $value ) ) recur_sort( $value );
}
if ( is_sequential_array( $array ) ) {
$array = array_map( function( $el ) { return json_encode( $el ); }, $array );
sort( $array, SORT_STRING );
$array = array_map( function( $el ) { return json_decode( $el, true ); }, $array );
return;
} else {
return ksort( $array );
}
}
function is_sequential_array(Array &$a) {
$n = count($a);
for($i=0; $i<$n; $i++) {
if(!array_key_exists($i, $a)) {
return false;
}
}
return true;
}
示例(在 PHPUnit 中):
//A stricter and recursive assertEqualsCanonicalizing
public function assertSameCanonicalizing( $expected, $actual ) {
recur_sort( $expected );
recur_sort( $actual );
$this->assertSame( $expected, $actual );
}
如果要检查数组是否具有严格相等 (===
) 的键和值关联,可以使用以下函数:
function array_eq($a, $b) {
// If the objects are not arrays or differ in their size, they cannot be equal
if (!is_array($a) || !is_array($b) || count($a) !== count($b)) {
return false;
}
// If the arrays of keys are not strictly equal (after sorting),
// the original arrays are not strictly equal either
$a_keys = array_keys($a);
$b_keys = array_keys($b);
array_multisort($a_keys);
array_multisort($b_keys);
if ($a_keys !== $b_keys) {
return false;
}
// Comparing values
foreach ($a_keys as $key) {
$a_value = $a[$key];
$b_value = $b[$key];
// Either the objects are strictly equal or they are arrays
// which are equal according to our definition. Otherwise they
// are different.
if ($a_value !== $b_value && !array_eq($a_value, $b_value)) {
return false;
}
}
return true;
}
使用 php 函数 array_diff(array1, array2);
它将返回数组之间的差异。如果它是空的,那么它们是相等的。
例子:
$array1 = array(
'a' => 'value1',
'b' => 'value2',
'c' => 'value3'
);
$array2 = array(
'a' => 'value1',
'b' => 'value2',
'c' => 'value4'
);
$diff = array_diff(array1, array2);
var_dump($diff);
//it will print array = (0 => ['c'] => 'value4' )
示例 2:
$array1 = array(
'a' => 'value1',
'b' => 'value2',
'c' => 'value3',
);
$array2 = array(
'a' => 'value1',
'b' => 'value2',
'c' => 'value3',
);
$diff = array_diff(array1, array2);
var_dump($diff);
//it will print empty;
(count(array_diff($a1, $a2)) + count(array_diff($a2, $a1))) === 0
来测试数组是否“相等”
不定期副业成功案例分享
array_values($a)==array_values($b)
...另一个常见的问题是关于唯一值,所以请记住存在array_unique()
。['a', 'b']
是数组[0 => 'a', 1 => 'b']
,而['b', 'a']
是数组[0 => 'b', 1 => 'a']
。这就是为什么它们没有我的回答中所述的相同键/值对,这就是为什么==
在它们之间不起作用的原因。