[2,5,3]
[5,2,3]
它们是相等的,因为它们具有相同的值,但不是相同的顺序。
我可以不使用foreach()
和in_array()
循环来找出吗? 我认为这样效率不高。
[2,5,3]
[5,2,3]
它们是相等的,因为它们具有相同的值,但不是相同的顺序。
我可以不使用foreach()
和in_array()
循环来找出吗? 我认为这样效率不高。
sort($a);
sort($b);
if ($a===$b) {//equal}
['a']
和 [true]
都返回 true。 - Jay Bienvenu===
代替==
测试了这个案例,['a']
和[true]
返回false。请注意不改变原意,使句子通俗易懂。 - Cameron Wilby===
,我会点赞的,但是没有那个额外的 =,这就不是最正确的答案了。 - Chris我来晚了。我有同样的问题,但不想进行排序,这是我知道会起作用的直接答案。我想出了这个简单的单行代码,但它只适用于唯一值的数组:
$same = ( count( $a ) == count( $b ) && !array_diff( $a, $b ) )
它也比排序选项快约5倍。 两者都不是特别慢,所以我认为更多关于您个人偏好,以及哪个选项更清晰。就我个人而言,我宁愿不排序。
编辑:感谢Ray指出这只适用于具有唯一值的数组。
$a = ['red','red','blue','blue'];
$b = ['red','red','red','blue'];
- Ray[true]
和 [1]
,返回 true
。 - Jay Bienvenu虽然有点晚了,但希望这对你有所帮助:
如果你确定两个数组中只包含字符串或只包含整数,则 array_count_values($a) == array_count_values($b)
的时间复杂度更好。但是,user1844933的答案更加通用。
array_count_values()
可能会生成负值。 - mickmackusa$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';
}
[true]
和 [1]
,返回 true
。 - Jay Bienvenu由于所有与键完全无关的给定答案都无法处理重复值(例如[1,1,2]
等于[1,2,2]
),因此我编写了自己的代码。
这个变体不能处理多维数组。 它会检查两个数组是否包含完全相同的值,而不考虑它们的键和顺序,而且不修改任何参数。
function array_equals(array $either, array $other) : bool {
foreach ($other as $element) {
$key = array_search($element, $either, true);
if ($key === false) {
return false;
}
unset($either[$key]);
}
return empty($either);
}
$either = $myarray;
// inline code from function above
最好的方法是使用 array_diff
函数,详情请见 http://php.net/manual/en/function.array-diff.php
$arr1 = [2,5,3];
$arr2 = [5,2,3];
$isEqual = array_diff($arr1,$arr2) === array_diff($arr2,$arr1);
array_diff($arr1, $arr2) === array_diff($arr2, $arr1) && count($arr1) === count($arr2)
。 - Chrissort($a);
sort($b);
$a_str = implode(",", $a);
$b_str = implode(",", $b);
f ( strcmp($a_str, $b_str) !== 0)
{
}
function array_equal($a, $b){
return count($a) === count($b) && empty(array_diff($a, $b)) && empty(array_diff($b, $a));
}
$array1 = array(2,5,3);
$array2 = array(5,2,3);
if(array_diff($array1,$array2) === array_diff($array2,$array1) &&count($array1)==count($array2))
{
echo 'Equal';
}
else
{
echo 'Not equal';
}
给出的答案包含各种怪癖,证明这不是一个简单的问题,并且在您的领域中定义“相同值”的含义非常重要。我对此的解决方案需要实现以下设计目标:
评估解决方案的测试用例如下:
<?php
namespace App\Tests\Unit\Utility;
use App\Utility\ArrayUtil;
use PHPUnit\Framework\TestCase;
class ArrayUtilTest extends TestCase {
/**
* @dataProvider elementsEqualDataProviderTrueCases
*/
public function test_elements_are_equal_true_cases(array $array1, array $array2): void {
$originalArray1 = serialize($array1);
$originalArray2 = serialize($array2);
$this->assertTrue(ArrayUtil::elementsEqual($array1, $array2));
$this->assertSame($originalArray1, serialize($array1));
$this->assertSame($originalArray2, serialize($array2));
}
/**
* @dataProvider elementsEqualDataProviderFalseCases
*/
public function test_elements_are_equal_false_cases(array $array1, array $array2): void {
$originalArray1 = serialize($array1);
$originalArray2 = serialize($array2);
$this->assertFalse(ArrayUtil::elementsEqual($array1, $array2));
$this->assertSame($originalArray1, serialize($array1));
$this->assertSame($originalArray2, serialize($array2));
}
/**
* @dataProvider exceptionTestCases
*/
public function test_elements_are_equal_exceptional_cases(mixed $array1, mixed $array2, string $exception): void {
$this->expectException($exception);
$originalArray1 = serialize($array1);
$originalArray2 = serialize($array2);
$this->assertFalse(ArrayUtil::elementsEqual($array1, $array2));
$this->assertSame($originalArray1, serialize($array1));
$this->assertSame($originalArray2, serialize($array2));
}
public function elementsEqualDataProviderTrueCases(): \Generator {
yield 'Empty arrays' => [
[],
[],
];
yield 'Integer types' => [
[1, 2, 3],
[3, 2, 1],
];
yield 'Boolean types' => [
[true, false],
[false, true],
];
yield 'String types' => [
["abc", "def"],
["def", "abc"],
];
$objectA = new \stdClass();
$objectB = new \stdClass();
yield 'Object types' => [
[$objectA, $objectB],
[$objectB, $objectA],
];
$objectC = new \stdClass();
yield 'Mixed types' => [
[2, true, "foo", null, $objectC],
["foo", null, 2, true, $objectC],
];
yield 'Array types' => [
[[1, 2], [3, 4]],
[[3, 4], [1, 2]],
];
yield 'Repeated values' => [
[1, 1, 2],
[2, 1, 1],
];
}
public function elementsEqualDataProviderFalseCases(): \Generator {
yield 'Integer types' => [
[1, 2, 3],
[4, 5, 6],
];
yield 'Boolean types' => [
[true],
[false],
];
yield 'String types' => [
["abc", "def"],
["hij", "abc"],
];
yield 'Object types' => [
[new \stdClass(), new \stdClass()],
[new \stdClass(), new \stdClass()],
];
$objectC = new \stdClass();
yield 'Mixed types' => [
[2, false, "foo", null, $objectC],
["foo", null, 2, true, $objectC],
];
yield 'Array types' => [
[[1, 2], [3, 4]],
[[4, 3], [2, 1]],
];
yield 'Repeated values' => [
[1, 1, 2],
[2, 2, 1],
];
yield 'Repeated values, longer second argument' => [
[1, 1, 2],
[2, 2, 1, 1],
];
yield 'Repeated values, longer first argument' => [
[1, 1, 2, 2],
[2, 2, 1],
];
}
public function exceptionTestCases(): \Generator {
yield 'Non-list array first argument' => [
['foo' => 'bar'],
[1, 2, 3],
\InvalidArgumentException::class,
];
yield 'Non-list array second argument' => [
[1, 2, 3],
['foo' => 'bar'],
\InvalidArgumentException::class,
];
yield 'Non array arguments' => [
"foo",
"bar",
\TypeError::class,
];
}
}
解决方案(主要改编自seyfahni的答案):
<?php
namespace App\Utility;
final class ArrayUtil {
public static function elementsEqual(array $array1, array $array2): bool {
if (!array_is_list($array1) || !array_is_list($array2)) {
throw new \InvalidArgumentException('Arrays compared for element equality must both be lists.');
}
if (count($array1) !== count($array2)) {
return false;
}
foreach ($array1 as $element) {
$key = array_search($element, $array2, true);
if ($key === false) {
return false;
}
unset($array2[$key]);
}
return empty($array2);
}
}
$array = array(4,3); $array2 = array(2,3,4); echo var_dump(array_diff($array,$array2));
- Suresh Kamrushi