如何知道两个数组的值是否相同

我有这两个数组: 一个数组填充来自 ajax 请求的信息,另一个数组存储用户单击的按钮。我使用这个代码(我用样本号码填充) :

var array1 = [2, 4];
var array2 = [4, 2]; //It cames from the user button clicks, so it might be disordered.
array1.sort(); //Sorts both Ajax and user info.
array2.sort();
if (array1==array2) {
doSomething();
}else{
doAnotherThing();
}

但它总是给出 false,即使这两个数组相同,但名称不同。(我在 Chrome 的 JS 控制台中检查了这一点)。那么,有没有办法知道这两个数组是否包含相同的内容呢?为什么是 false?如何知道第一个数组中的哪些值不在第二个数组中?

285573 次浏览
Array.prototype.compare = function(testArr) {
if (this.length != testArr.length) return false;
for (var i = 0; i < testArr.length; i++) {
if (this[i].compare) { //To test values in nested arrays
if (!this[i].compare(testArr[i])) return false;
}
else if (this[i] !== testArr[i]) return false;
}
return true;
}


var array1 = [2, 4];
var array2 = [4, 2];
if(array1.sort().compare(array2.sort())) {
doSomething();
} else {
doAnotherThing();
}

也许吧?

当您比较这两个数组时,您是在比较表示数组的对象,而不是内容。

您必须使用一个函数来比较两者。您可以编写自己的代码,在检查长度是否相同后,将其中一个循环并与另一个进行比较。

如果您的数组项不是对象——例如,如果它们是数字或字符串,您可以比较它们的连接字符串,以查看它们是否以任何顺序具有相同的成员——

var array1= [10, 6, 19, 16, 14, 15, 2, 9, 5, 3, 4, 13, 8, 7, 1, 12, 18, 11, 20, 17];
var array2= [12, 18, 20, 11, 19, 14, 6, 7, 8, 16, 9, 3, 1, 13, 5, 4, 15, 10, 2, 17];


if(array1.sort().join(',')=== array2.sort().join(',')){
alert('same members');
}
else alert('not a match');

如果您正在使用 Prototype Framework,您可以使用数组的 互联系统方法来发现它们是相同的(不管顺序如何) :

var array1 = [1,2];
var array2 = [2,1];


if(array1.intersect(array2).length === array1.length) {
alert("arrays are the same!");
}

对象相等性检查: JSON.stringify(array1.sort()) === JSON.stringify(array2.sort())

上面的测试也适用于对象数组,在这种情况下使用 http://www.w3schools.com/jsref/jsref_sort.asp中记录的排序函数

对于具有平面 JSON 模式的小型数组可能就足够了。

如果只想检查两个数组是否具有相同的值(不管出现的次数和每个值的顺序) ,可以使用 浪荡:

_.isEmpty(_.xor(array1, array2))

简短,简单,漂亮!

我在 Game 项目中使用了简单的整数值
每个数组中的值数量较少,也需要原始数组保持不变
所以,我做了下面的工作,它工作得很好。(代码编辑粘贴在这里)

var sourceArray = [1, 2, 3];
var targetArray = [3, 2, 1];


if (sourceArray.length !== targetArray.length) {
// not equal
// did something
return false;
}


var newSortedSourceArray = sourceArray.slice().sort();
var newSortedTargetArray = targetArray.slice().sort();


if (newSortedSourceArray.toString() !== newSortedTargetArray.toString()) { // MAIN CHECK
// not equal
// did something
return false;
}
else {
// equal
// did something
// continued further below
}


// did some more work


return true;

希望能帮上忙。

为什么你的代码不起作用

JavaScript 具有 基本数据类型和非基元数据类型。

对于基本数据类型,=====检查条形图两边的值是否相同。这就是为什么 1 === 1是真的。

对于非基元数据类型(如数组) ,=====检查引用是否相等。也就是说,它们检查 arr1arr2是否是同一个对象。在您的示例中,两个数组具有相同顺序的相同对象,但并不等效。

解决方案

两个数组 arr1arr2具有相同的成员当且仅当:

  • arr2里的一切都在 arr1

还有

  • arr1里的一切都在 arr2

因此,这将会奏效(ES2016) :

const containsAll = (arr1, arr2) =>
arr2.every(arr2Item => arr1.includes(arr2Item))
                

const sameMembers = (arr1, arr2) =>
containsAll(arr1, arr2) && containsAll(arr2, arr1);


sameMembers(arr1, arr2); // `true`

使用 下划线的第二种解决方案更接近于您试图做的事情:

arr1.sort();
arr2.sort();


_.isEqual(arr1, arr2); // `true`

它工作是因为 isEqual检查“深度相等”,这意味着它不仅仅检查引用相等和比较值。

你第三个问题的答案

您还询问如何找出 arr1中的哪些内容不包含在 arr2中。

这样就行了(ES2015) :

const arr1 = [1, 2, 3, 4];
const arr2 = [3, 2, 1];


arr1.filter(arr1Item => !arr2.includes(arr1Item)); // `[4]`

你也可以使用 Underscore 的 difference: 方法:

_.difference(arr1, arr2); // `[4]`

更新

请看@Redu 的评论ーー我的解决方案是 sameMembers,但您可能想到的是 sameMembersInOrder,也称为 deepEquals

更新2

如果您不关心数组成员的顺序,ES2015 + 的 Set可能是比 Array更好的数据结构。看到 MDN 关于如何实现 ABC2和 difference的说明使用危险的猴子补丁。

更新3

如果顺序不重要,还是使用集合更好。但是,如果必须使用数组,这个解决方案的时间复杂度比我之前给出的解决方案更高:

function sameMembers(arr1, arr2) {
const set1 = new Set(arr1);
const set2 = new Set(arr2);
return arr1.every(item => set2.has(item)) &&
arr2.every(item => set1.has(item))
}

对数组进行排序并逐个比较它们的值。

function arrayCompare(_arr1, _arr2) {
if (
!Array.isArray(_arr1)
|| !Array.isArray(_arr2)
|| _arr1.length !== _arr2.length
) {
return false;
}
    

// .concat() to not mutate arguments
const arr1 = _arr1.concat().sort();
const arr2 = _arr2.concat().sort();
    

for (let i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) {
return false;
}
}
    

return true;
}

请检查这个答案

var arr1= [12,18];
var arr2= [12, 18, 20, 11, 19, 14, 6, 7, 8, 16, 9, 3, 1, 13, 5, 4, 15, 10, 2, 17];
for(i=0;i<arr1.length;i++)
{
var array1=arr1[i];
for(j=0;j<arr2.length;j++)
{
var array2=arr2[j];
if(array1==array2)
{
return true;
}
}
}

使用 ES6

我们将使用 Ramda 的 equals函数,但是我们可以使用 Lodash 的或者 Underscore 的 isEqual:

const R = require('ramda');


const arraysHaveSameValues = (arr1, arr2) => R.equals( [...arr1].sort(), [...arr2].sort() )

通过使用扩展操作符,我们避免了对原始数组进行变异,并且保持了函数的纯粹性。

我们的目的基本上是检查2个数组是否相等。准备好了是数学上定义的 < em > set 。最快的渐近排序需要 O (nlog (n))时间。因此,如果对一个数组排序,它至少需要 O (nlog (n))时间。但是您的 可以更快地完成这项任务,它采用字典数据结构,渐近占用 O (n)时间(平均情况不是最坏情况)。在 JS 中,dictionary 只是一个带有键和值的对象。

/** assumes array elements are primitive types
* check whether 2 arrays are equal sets.
* @param  {} a1 is an array
* @param  {} a2 is an array
*/
function areArraysEqualSets(a1, a2) {
const superSet = {};
for (const i of a1) {
const e = i + typeof i;
superSet[e] = 1;
}


for (const i of a2) {
const e = i + typeof i;
if (!superSet[e]) {
return false;
}
superSet[e] = 2;
}


for (let e in superSet) {
if (superSet[e] === 1) {
return false;
}
}


return true;
}

注意,这个函数使用基元类型的数组,并假设 a1a2是数组。

回答了很长时间,但希望这将帮助有人谁寻找一个简单的解决方案和现代新手。

现在,我们可以使用多个库来实现这一点,如 lodashunderscore等(这些库由于简单、多功能和高使用率而成为当今项目的一部分)

您可以使用来自洛达什库的交集。

_.intersection(['2-1', '1'], ['2-2', '3-1', '2-1']);
// => ['2-1']

这将适用于任何数据类型. 。

如果你想比较两个数组,并检查是否有任何对象是相同的两个数组,它将工作。 例如:

数组1 = [ a,b,c,d ]
数组2 = [ d,e,f,g ]

在这里,“ d”在两个数组中都很常见,因此这个函数将返回真值。

  cehckArray(array1, array2) {
for (let i = 0; i < array1.length; i++) {
for (let j = 0; j < array2.length; j++) {
if (array1[i] === array2[j]) {
return true;
}
}
}
// Return if no common element exist
return false;
}

这个怎么样? ES 2017我想:

const array1 = [1, 3, 5];
const array2 = [1, 5, 3];


const isEqual = (array1.length === array2.length) && (array1.every(val => array2.includes(val)));
console.log(isEqual);

第一个条件检查两个数组的长度是否相同,第二个条件检查第一个数组是否是第二个数组的子集。结合这两个条件应该导致比较的所有项目的2个阵列,无论顺序的元素。

上面的代码只有在两个数组都有非重复项的情况下才能工作。

您可以使用 reduce而不是循环来显得聪明,但是这样做可能会让您的开发人员同事认为您是一个自作聪明的人。

function isArrayContentSame(a, b) {
if (Array.isArray(a) && Array.isArray(b) && a.length == b.length) {
a = a.concat().sort()
b = b.concat().sort()
return a.reduce((acc,e,i) => acc && e === b[i], true)
} else {
return false;
}
}

使用 ES6实现浅相等的简单解决方案:

const arr1test = arr1.slice().sort()
const arr2test = arr2.slice().sort()
const equal = !arr1test.some((val, idx) => val !== arr2test[idx])


创建每个数组的浅副本并对它们进行排序。然后使用 some()循环遍历 arr1test值,使用相同的索引对 arr2test中的值检查每个值。如果所有值都相等,则 some()返回 false,而 equal则计算为 true

也可以使用 every(),但是它必须循环遍历数组中的每个元素以满足 true的结果,而 some()一旦发现一个不相等的值就会立即停止:

const equal = arr1test.every((val, idx) => val === arr2test[idx])

比较两个数组的简单解决方案:

var array1 = [2, 4];
var array2 = [4, 2];


array1.sort();
array2.sort();


if (array1[0] == array2[0]) {
console.log("Success");
}else{
console.log("Wrong");
}

试试这个

function arraysEqual(arr1, arr2){
if (!Array.isArray(arr1) || !Array.isArray(arr2) || arr1.length!=arr2.length)
return false;


return arr1.length==arr1.filter(word => arr2.includes(word)).length;
}

我有另一种方法,基于接受的答案。

function compareArrays(array1, array2) {


if (
!Array.isArray(array1)
|| !Array.isArray(array2)
|| array1.length !== array2.length
) return false;


var first = array1.sort().map(value => (String(value))).join();
var second = array2.sort().map(value => (String(value))).join();


return first == second ? true : false;
}

比较两个数组的函数,检查两个数组是否有相同的元素。即使它们不正常..。

它适用于简单的数组[ String,Number,Boolean,null,NaN ]。

我不使用. sort () ,它修改原始数组。有人说它不好..。

注意: 这个函数是有限的,它不能比较对象“[] ,{}”或者这些数组中的函数,数组本身就是对象。

   let arraysHasSameElements = (arr1, arr2) => {
let count =
// returns counting of occurrences.
(arr, val) => arr.reduce((count, curr) => (curr === val ? 1 : 0) + count, 0);


/* this will return true if lengths of the arrays is equal.
then compare them.*/
return arr1.length === arr2.length


// compare arr1 against arr2.
&& arr1.reduce((checks, val) =>


/*  creating array of checking if a value has equal amount of occurrences
in both arrays, then adds true 'check'. */
checks.concat(count(arr1, val) === count(arr2, val)), [])


// checking if each check is equal to true, then .every() returns true.
.every(check => check);
}


let arr1 = ['',-99,true,NaN,21,null,false,'help',-99,'help',NaN],
arr2 = [null,-99,'',NaN,NaN,false,true,-99,'help',21,'help'];
arraysHasSameElements(arr1, arr2); //true


let arr3 = [false,false,false,false,false,false],
arr4 = [false,false,false,false,false,false]
arraysHasSameElements(arr3, arr4); //true




// here we have uncommented version.
let arraysHasSameElements = (arr1, arr2) => {
let count = (arr, val) => arr.reduce((count, curr) => (curr === val ? 1:0) + count, 0);
return arr1.length === arr2.length && arr1.reduce((checks, val) =>
checks.concat(count(arr1, val) === count(arr2, val)), []).every(check => check);
}


大多数其他解决方案使用 sort、 O (n * log n)、使用库或具有 O (n ^ 2)复杂性。

下面是一个线性复杂度为 O (n)的纯 Javascript 解决方案:

/**
* Check if two arrays of strings or numbers have the same values
* @param {string[]|number[]} arr1
* @param {string[]|number[]} arr2
* @param {Object} [opts]
* @param {boolean} [opts.enforceOrder] - By default (false), the order of the values in the arrays doesn't matter.
* @return {boolean}
*/
function compareArrays(arr1, arr2, opts) {


function vKey(i, v) {
return (opts?.enforceOrder ? `${i}-` : '') + `${typeof v}-${v}`
}


if (arr1.length !== arr2.length) return false;


const d1 = {};
const d2 = {};
for (let i = arr1.length - 1; i >= 0; i--) {
d1[vKey(i, arr1[i])] = true;
d2[vKey(i, arr2[i])] = true;
}
  

for (let i = arr1.length - 1; i >= 0; i--) {
const v = vKey(i, arr1[i]);
if (d1[v] !== d2[v]) return false;
}


for (let i = arr2.length - 1; i >= 0; i--) {
const v = vKey(i, arr2[i]);
if (d1[v] !== d2[v]) return false;
}


return true
}

测试:

arr1= [1, 2]
arr2= [1, 2]
compareArrays(arr1, arr2) => true
compareArrays(arr1, arr2, {enforceOrder: true}) => true
-------
arr1= [1, 2]
arr2= [2, 1]
compareArrays(arr1, arr2) => true
compareArrays(arr1, arr2, {enforceOrder: true}) => false
-------
arr1= [2, 1]
arr2= [1, 2]
compareArrays(arr1, arr2) => true
compareArrays(arr1, arr2, {enforceOrder: true}) => false
-------
arr1= [2, 2]
arr2= [1, 2]
compareArrays(arr1, arr2) => false
compareArrays(arr1, arr2, {enforceOrder: true}) => false
-------
arr1= [1, 2]
arr2= [1, 2, 3]
compareArrays(arr1, arr2) => false
compareArrays(arr1, arr2, {enforceOrder: true}) => false
-------
arr1= ["1"]
arr2= [1]
compareArrays(arr1, arr2) => false
compareArrays(arr1, arr2, {enforceOrder: true}) => false
-------
arr1= ["1", 2]
arr2= [2, "1"]
compareArrays(arr1, arr2) => true
compareArrays(arr1, arr2, {enforceOrder: true}) => false
-------
arr1= []
arr2= []
compareArrays(arr1, arr2) => true
compareArrays(arr1, arr2, {enforceOrder: true}) => true

你似乎并不在乎性别,也不确定其他答案是否在乎。

下面是 sameArrayMembers(即 [1,2,2] != [1,1,2])和 sameArrayMembersAsSet(即 [1,2,2] == [1,1,2])的一些基准测试

没有检查 [1,1,2]相同的 [1,2],我可能应该给,如果你声称检查集比你不应该有长度检查。

const tests = {
'Maciej Krawczyk': (_arr1, _arr2) => {


if (!Array.isArray(_arr1) || ! Array.isArray(_arr2) || _arr1.length !== _arr2.length)
return false;


var arr1 = _arr1.concat().sort();
var arr2 = _arr2.concat().sort();


for (var i = 0; i < arr1.length; i++) {


if (arr1[i] !== arr2[i])
return false;


}


return true;
},
'canbax': (a1, a2) => {
const superSet = {};
for (const i of a1) {
const e = i + typeof i;
superSet[e] = 1;
}


for (const i of a2) {
const e = i + typeof i;
if (!superSet[e]) {
return false;
}
superSet[e] = 2;
}


for (let e in superSet) {
if (superSet[e] === 1) {
return false;
}
}


return true;
},
'kennebec': (array1, array2) => {
return array1.slice().sort().join(',')=== array2.slice().sort().join(',');
},
'Max Heiber': function() {
const containsAll = (arr1, arr2) =>
arr2.every(arr2Item => arr1.includes(arr2Item));
return (arr1, arr2) =>
containsAll(arr1, arr2) && containsAll(arr2, arr1);
}(),
'gman': (a, b) => {
if (a.length !== b.length) { return false; }
const counts = new Map();
for (const v of a) {
const count = counts.get(v) || 0;
counts.set(v, count + 1);
}
for (const v of b) {
const count = counts.get(v);
if (!count) {   // undefined or 0, both mean arrays are not the same
return false;
}
counts.set(v, count - 1);
}
return true;
},
'Bemmu': (a, b) => {
if (Array.isArray(a) && Array.isArray(b) && a.length == b.length) {
a = a.concat().sort()
b = b.concat().sort()
return a.reduce((acc,e,i) => acc && e === b[i], true)
} else {
return false;
}
},
'Sandeep': (array1, array2) => {
return JSON.stringify(array1.sort()) === JSON.stringify(array2.sort());
},
'camslice': (arr1, arr2) => {
const arr1test = arr1.slice().sort();
const arr2test = arr2.slice().sort();
return !arr1test.some((val, idx) => val !== arr2test[idx]);
},
'Dimitrios Stefos': (arr1, arr2) => {
if (!Array.isArray(arr1) || !Array.isArray(arr2) || arr1.length!=arr2.length)
return false;


return arr1.length==arr1.filter(word => arr2.includes(word)).length;
},
'SC1000': (arr1, arr2, opts) => {
function vKey(i, v) {
return (opts?.enforceOrder ? `${i}-` : '') + `${typeof v}-${v}`
}


if (arr1.length !== arr2.length) return false;


const d1 = {};
const d2 = {};
for (let i = arr1.length - 1; i >= 0; i--) {
d1[vKey(i, arr1[i])] = true;
d2[vKey(i, arr2[i])] = true;
}


for (let i = arr1.length - 1; i >= 0; i--) {
const v = vKey(i, arr1[i]);
if (d1[v] !== d2[v]) return false;
}


for (let i = arr2.length - 1; i >= 0; i--) {
const v = vKey(i, arr2[i]);
if (d1[v] !== d2[v]) return false;
}


return true
},
'Magnus Fohlström': (arr1, arr2) => {
let count = (arr, val) => arr.reduce((count, curr) => (curr === val ? 1:0) + count, 0);
return arr1.length === arr2.length && arr1.reduce((checks, val) =>
checks.concat(count(arr1, val) === count(arr2, val)), []).every(check => check);
},
};


// ----------------------------


function createExposedPromise() {
const p = {};
p.promise = new Promise((resolve, reject) => {
p.resolve = resolve;
p.reject = reject;
});
return p;
}


function assert(cond) {
if (!cond) {
log('assert');
throw new Error();
}
}


async function main() {
await testResults(true, 'sameArrayMembers');
await testResults(false, 'sameArrayMemembersAsSet');
  

async function testResults(asSet, msg) {
log(`\n=======[ ${msg} ] ============`);
const suite = new Benchmark.Suite();
let test;


// reject if they fail simple test
const a = [1,1,2];
const b = [1,2,2];
for (const [name, fn] of Object.entries(tests)) {
if (fn(a, b) === asSet) {
log(`${name} fails for ${msg}([${a}], [${b}])`);
} else {
suite.add(name, () => test(fn));
}
}


let endPromise;


suite.on('cycle', event => log(String(event.target)));
suite.on('complete', function() {
log('Fastest is ' + this.filter('fastest').map('name'));
endPromise.resolve();
});


async function runWith(num, title) {
log(`------[ ${title} ] -----------`);


const a = [];
for (let i = 0; i < num; ++i) {
a[i] = Math.random();
}
const b = [...a];
const c = [...a]; c[c.length / 2 | 0]++;


endPromise = createExposedPromise();


test = (fn) => {
assert(fn(a, b))
assert(!fn(a, c));
};


suite.reset();
suite.run({'async': true});
await endPromise.promise;
}


await runWith(10, 'small (10)');
await runWith(100, 'medium (100)');
await runWith(10000, 'large (10000)');
}
}
main();


function log(...args) {
const elem = document.createElement('pre');
elem.textContent = args.join(' ');
document.body.appendChild(elem);
}
pre { margin: 0; }
<script src="https://unpkg.com/lodash@4.17.20/lodash.js"></script>
<script src="https://unpkg.com/benchmark@2.1.4/benchmark.js"></script>

结果可能会随着时间的推移而改变,因为 JS 引擎得到了更新

铬87

=======[ sameArrayMembers ] ============
canbax fails for sameArrayMembers([1,1,2], [1,2,2])
Max Heiber fails for sameArrayMembers([1,1,2], [1,2,2])
Dimitrios Stefos fails for sameArrayMembers([1,1,2], [1,2,2])
SC1000 fails for sameArrayMembers([1,1,2], [1,2,2])
------[ small (10) ] -----------
Maciej Krawczyk x 246,129 ops/sec ±0.84% (66 runs sampled)
kennebec x 182,234 ops/sec ±0.56% (64 runs sampled)
gman x 377,356 ops/sec ±1.55% (64 runs sampled)
Bemmu x 244,850 ops/sec ±0.76% (64 runs sampled)
Sandeep x 100,529 ops/sec ±1.53% (63 runs sampled)
camslice x 542,577 ops/sec ±0.68% (64 runs sampled)
Fastest is camslice
------[ medium (100) ] -----------
Maciej Krawczyk x 12,121 ops/sec ±1.40% (63 runs sampled)
kennebec x 10,219 ops/sec ±1.60% (63 runs sampled)
gman x 41,225 ops/sec ±1.63% (62 runs sampled)
Bemmu x 12,400 ops/sec ±1.10% (63 runs sampled)
Sandeep x 12,470 ops/sec ±0.50% (64 runs sampled)
camslice x 57,126 ops/sec ±0.54% (64 runs sampled)
Fastest is camslice
------[ large (10000) ] -----------
Maciej Krawczyk x 30.75 ops/sec ±0.86% (42 runs sampled)
kennebec x 27.35 ops/sec ±1.11% (38 runs sampled)
gman x 376 ops/sec ±0.46% (62 runs sampled)
Bemmu x 30.91 ops/sec ±0.77% (42 runs sampled)
Sandeep x 80.33 ops/sec ±0.54% (53 runs sampled)
camslice x 166 ops/sec ±0.44% (61 runs sampled)
Fastest is gman


=======[ sameArrayMemembersAsSet ] ============
Maciej Krawczyk fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
kennebec fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
gman fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
Bemmu fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
Sandeep fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
camslice fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
------[ small (10) ] -----------
canbax x 110,826 ops/sec ±2.07% (63 runs sampled)
Max Heiber x 2,699,807 ops/sec ±1.31% (63 runs sampled)
Dimitrios Stefos x 2,910,096 ops/sec ±0.65% (62 runs sampled)
SC1000 x 59,989 ops/sec ±2.61% (63 runs sampled)
Fastest is Dimitrios Stefos
------[ medium (100) ] -----------
canbax x 9,624 ops/sec ±2.20% (53 runs sampled)
Max Heiber x 88,945 ops/sec ±0.71% (64 runs sampled)
Dimitrios Stefos x 94,425 ops/sec ±0.51% (65 runs sampled)
SC1000 x 5,742 ops/sec ±0.74% (33 runs sampled)
Fastest is Dimitrios Stefos
------[ large (10000) ] -----------
canbax x 59.85 ops/sec ±1.69% (46 runs sampled)
Max Heiber x 13.50 ops/sec ±0.87% (26 runs sampled)
Dimitrios Stefos x 15.40 ops/sec ±0.89% (30 runs sampled)
SC1000 x 37.42 ops/sec ±1.47% (40 runs sampled)
Fastest is canbax

火狐80

=======[ sameArrayMembers ] ============
canbax fails for sameArrayMembers([1,1,2], [1,2,2])
Max Heiber fails for sameArrayMembers([1,1,2], [1,2,2])
Dimitrios Stefos fails for sameArrayMembers([1,1,2], [1,2,2])
SC1000 fails for sameArrayMembers([1,1,2], [1,2,2])
------[ small (10) ] -----------
Maciej Krawczyk x 118,391 ops/sec ±0.52% (65 runs sampled)
kennebec x 70,254 ops/sec ±0.40% (67 runs sampled)
gman x 201,659 ops/sec ±3.23% (57 runs sampled)
Bemmu x 118,133 ops/sec ±0.67% (64 runs sampled)
Sandeep x 69,484 ops/sec ±1.40% (65 runs sampled)
camslice x 130,443 ops/sec ±0.55% (65 runs sampled)
Fastest is gman
------[ medium (100) ] -----------
Maciej Krawczyk x 11,418 ops/sec ±2.81% (61 runs sampled)
kennebec x 7,278 ops/sec ±1.37% (41 runs sampled)
gman x 19,748 ops/sec ±6.60% (53 runs sampled)
Bemmu x 11,535 ops/sec ±1.09% (62 runs sampled)
Sandeep x 8,234 ops/sec ±1.46% (45 runs sampled)
camslice x 14,277 ops/sec ±3.08% (60 runs sampled)
Fastest is gman
------[ large (10000) ] -----------
Maciej Krawczyk x 65.25 ops/sec ±2.13% (49 runs sampled)
kennebec x 47.73 ops/sec ±0.82% (51 runs sampled)
gman x 210 ops/sec ±3.54% (54 runs sampled)
Bemmu x 66.90 ops/sec ±0.53% (50 runs sampled)
Sandeep x 63.13 ops/sec ±1.59% (48 runs sampled)
camslice x 115 ops/sec ±1.36% (56 runs sampled)
Fastest is gman


=======[ sameArrayMemembersAsSet ] ============
Maciej Krawczyk fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
kennebec fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
gman fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
Bemmu fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
Sandeep fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
camslice fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
------[ small (10) ] -----------
canbax x 79,433 ops/sec ±1.11% (57 runs sampled)
Max Heiber x 1,822,200 ops/sec ±0.92% (65 runs sampled)
Dimitrios Stefos x 2,258,820 ops/sec ±0.48% (65 runs sampled)
SC1000 x 35,784 ops/sec ±1.42% (63 runs sampled)
Fastest is Dimitrios Stefos
------[ medium (100) ] -----------
canbax x 6,726 ops/sec ±0.60% (38 runs sampled)
Max Heiber x 41,620 ops/sec ±1.08% (65 runs sampled)
Dimitrios Stefos x 53,041 ops/sec ±1.61% (64 runs sampled)
SC1000 x 3,450 ops/sec ±0.56% (64 runs sampled)
Fastest is Dimitrios Stefos
------[ large (10000) ] -----------
canbax x 44.18 ops/sec ±5.87% (42 runs sampled)
Max Heiber x 5.62 ops/sec ±4.79% (19 runs sampled)
Dimitrios Stefos x 6.77 ops/sec ±1.21% (21 runs sampled)
SC1000 x 24.18 ops/sec ±3.50% (36 runs sampled)
Fastest is canbax

Safari 14

=======[ sameArrayMembers ] ============
canbax fails for sameArrayMembers([1,1,2], [1,2,2])
Max Heiber fails for sameArrayMembers([1,1,2], [1,2,2])
Dimitrios Stefos fails for sameArrayMembers([1,1,2], [1,2,2])
SC1000 fails for sameArrayMembers([1,1,2], [1,2,2])
------[ small (10) ] -----------
Maciej Krawczyk x 142,798 ops/sec ±0.50% (65 runs sampled)
kennebec x 118,073 ops/sec ±1.12% (63 runs sampled)
gman x 760,109 ops/sec ±0.46% (66 runs sampled)
Bemmu x 136,265 ops/sec ±0.48% (63 runs sampled)
Sandeep x 69,868 ops/sec ±0.44% (64 runs sampled)
camslice x 155,548 ops/sec ±0.45% (64 runs sampled)
Fastest is gman
------[ medium (100) ] -----------
Maciej Krawczyk x 8,479 ops/sec ±0.52% (46 runs sampled)
kennebec x 5,992 ops/sec ±2.54% (34 runs sampled)
gman x 83,390 ops/sec ±0.37% (64 runs sampled)
Bemmu x 8,615 ops/sec ±0.56% (63 runs sampled)
Sandeep x 5,943 ops/sec ±0.67% (64 runs sampled)
camslice x 8,753 ops/sec ±0.45% (47 runs sampled)
Fastest is gman
------[ large (10000) ] -----------
Maciej Krawczyk x 62.66 ops/sec ±0.87% (51 runs sampled)
kennebec x 46.46 ops/sec ±0.66% (48 runs sampled)
gman x 615 ops/sec ±2.33% (60 runs sampled)
Bemmu x 60.98 ops/sec ±1.28% (52 runs sampled)
Sandeep x 49.11 ops/sec ±2.07% (47 runs sampled)
camslice x 66.33 ops/sec ±4.44% (50 runs sampled)
Fastest is gman


=======[ sameArrayMemembersAsSet ] ============
Maciej Krawczyk fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
kennebec fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
gman fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
Bemmu fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
Sandeep fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
camslice fails for sameArrayMemembersAsSet([1,1,2], [1,2,2])
------[ small (10) ] -----------
canbax x 167,041 ops/sec ±0.63% (64 runs sampled)
Max Heiber x 1,281,054 ops/sec ±0.74% (59 runs sampled)
Dimitrios Stefos x 1,127,639 ops/sec ±0.98% (64 runs sampled)
SC1000 x 112,824 ops/sec ±0.37% (64 runs sampled)
Fastest is Max Heiber
------[ medium (100) ] -----------
canbax x 8,784 ops/sec ±0.53% (47 runs sampled)
Max Heiber x 37,824 ops/sec ±0.52% (65 runs sampled)
Dimitrios Stefos x 41,238 ops/sec ±0.85% (63 runs sampled)
SC1000 x 6,181 ops/sec ±0.61% (35 runs sampled)
Fastest is Dimitrios Stefos
------[ large (10000) ] -----------
canbax x 63.83 ops/sec ±2.46% (49 runs sampled)
Max Heiber x 5.41 ops/sec ±0.52% (18 runs sampled)
Dimitrios Stefos x 6.02 ops/sec ±1.32% (19 runs sampled)
SC1000 x 42.25 ops/sec ±1.45% (45 runs sampled)
Fastest is canbax

如果只想测试基元值,可以尝试:

if(JSON.stringify(arr1.sort()) !== JSON.stringify(arr2.sort())) {
console.log('invalid');
}

另一种解决方案是:

array1.concat(array2).filter((item, index, currentArr) => currentArr.lastIndexOf(item) == currentArr.indexOf(item)).length == 0;

或者

[...array1, ...array2].filter((item, index, currentArr) => currentArr.lastIndexOf(item) == currentArr.indexOf(item)).length == 0;

以下是我的不分类解决方案:

function isDifferent(t1,t2)
{
return ((t1.length !== t2.length) || t1.some(tag1 => !t2.some(t=>t===tag1)));
}


let a1=['t','','b','xx','i','p','i'];
let a2=['','o','xx','b','t','p','i'];


console.log("DIFFERENT=",isDifferent(a1,a2)); //false


a1=['a','c','d'];
a2=['a','c'];


console.log("DIFFERENT=",isDifferent(a1,a2)); //true


a1=['a','c','d'];
a2=['a','c','c'];


console.log("DIFFERENT=",isDifferent(a1,a2)); //true


a1=['a','b','c'];
a2=['c','b','a'];


console.log("DIFFERENT=",isDifferent(a1,a2)); //false

  1. 检查两个数组的值是否相同,但顺序可能不同

function compareArr(arr1, arr2) {
return arr1.sort().join(',') == arr2.sort().join(',');
}


console.log(compareArr([1,2,3],[1,2,3])); // returns true
console.log(compareArr([1,2,3],[3,2,1])); // returns true
console.log(compareArr([1,2,3],[3,4,1])); // returns false

  1. 检查两个数组是否具有相同的值和相同的顺序(只是不要对它们进行排序)

function compareArrOrder(arr1, arr2) {
return arr1.join(',') == arr2.join(',');
}


console.log(compareArrOrder([1,2,3],[1,2,3])); // returns true
console.log(compareArrOrder([1,2,3],[3,2,1])); // returns false
console.log(compareArrOrder([1,2,3],[3,4,1])); // returns false

代码及说明

function arrayEquals(arr1, arr2) {
// compare array lengths, if not equal then skip.
if (arr1.length !== arr2.length) return false;


// setup a variable of the array length
let i = arr1.length;


// iterate through every element in arr1 basically...
while (i--) {
// if arr2 doesn't include x element from arr1, return false
if (!arr2.includes(arr1[i])) return false;


// passes tests and checks out
};
return true;
}


// works with multiple types
let foo = ["foo", "bar", 1, 2, true];
let bar = ["bar", 2, true, "foo", 1];


console.log(foo,bar,"Should return true: " + arrayEquals(foo, bar));


let fob = ["bar", "foo"];
let oar = ["oar", "foo"];


console.log(fob,oar,"Should return false (bar ≠ oar): " + arrayEquals(fob, oar));

免责声明

这只支持简单的类型,比如字符串、数字、布尔值等。除非编辑代码使其递归,否则它不会深入研究对象或数组,但是就回答问题本身而言,这似乎并不是一个问题。你提供了数字,所以我的答案就是数字。

这对我来说很好用,但是我不明白为什么有些人在数组上使用 concat 方法。

/**
*
* @param {Array} firstArray
* @param {Array} secondArray
* @returns {boolean}
*/
function arrayIsEqual(firstArray, secondArray)
{
if (
!Array.isArray(firstArray)
|| !Array.isArray(secondArray)
|| firstArray.length !== secondArray.length
) {
console.log('Bad params!\n');
return false;
}
$bool = firstArray === secondArray || firstArray.every((x,i)=> Array.isArray(x) ? arrayIsEqual(x, secondArray[i]) : x === secondArray[i]);
console.log($bool);
return $bool;
}


let a = [1, 2];
let b = [3, 4];
let c = "Me and you";
let d = [1, [2, 3, 5], 4];
let e = [1, [2, 3, 5], 4];
let f = [1, [2, 3, 5], [4]];
let g = [1, [2, 3, 5], [4]];


arrayIsEqual(a, b);
arrayIsEqual(b, c);
arrayIsEqual(c, a);
arrayIsEqual(a, a);
arrayIsEqual(d, e);
arrayIsEqual(e, f);
arrayIsEqual(e, e);
arrayIsEqual(g, f);

输出

false
Bad params!


Bad params!


true
true
true
true
false
true
true
true
true

如果数组元素的顺序不重要,可以尝试

function arraysEqual<T>(a:T[], b:T[]) {
if (a === b) return true;
if (a == null || b == null) return false;
if (a.length !== b.length) return false;




const aClone = [...a].sort();
const bClone = [...b].sort();
for (var i = 0; i < aClone.length; ++i) {
if (aClone[i] !== bClone[i]) return false;
}
return true;
}


const arr1 = [1,2,3,4];
const arr2 = [3,2,1,4];
console.log(arraysEqual(arr1, arr2)) //true

为了 ES6

var array1 = [2, 4];
var array2 = [4, 2];




let difference = array1.filter(x => !array2.includes(x));


console.log("equals", difference?.length != 0 ? false : true)

得到结果最简单的方法如下

const array1 = [1,2,3,4]


const array2 = [3,4,5,6]


const result = array1.filter(arr => array2.includes(arr))


console.log(result)