如何比较JavaScript中的数组?

我想比较两个arrays…理想,有效。 没有什么幻想,只要它们是相同的就是true假如没有,就是false 。 毫不奇怪,比较运算符似乎不起作用。

 var a1 = [1,2,3]; var a2 = [1,2,3]; console.log(a1==a2); // Returns false console.log(JSON.stringify(a1)==JSON.stringify(a2)); // Returns true 

每个数组的JSON编码不会,但有没有一种更快或“更好”的方式来比较数组而不必迭代每个值?

我真的不能相信有这么多人想要比较数组作为string 。 所以,虽然这是一个老问题,但我会添加正确的方式来比较数组 – 循环遍历它们并比较每个值:

正确的方式:

 // Warn if overriding existing method if(Array.prototype.equals) console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code."); // attach the .equals method to Array's prototype to call it on any array Array.prototype.equals = function (array) { // if the other array is a falsy value, return if (!array) return false; // compare lengths - can save a lot of time if (this.length != array.length) return false; for (var i = 0, l=this.length; i < l; i++) { // Check if we have nested arrays if (this[i] instanceof Array && array[i] instanceof Array) { // recurse into the nested arrays if (!this[i].equals(array[i])) return false; } else if (this[i] != array[i]) { // Warning - two different object instances will never be equal: {x:20} != {x:20} return false; } } return true; } // Hide method from for-in loops Object.defineProperty(Array.prototype, "equals", {enumerable: false}); 

用法:

 [1, 2, [3, 4]].equals([1, 2, [3, 2]]) === false; [1, "2,3"].equals([1, 2, 3]) === false; [1, 2, [3, 4]].equals([1, 2, [3, 4]]) === true; [1, 2, 1, 2].equals([1, 2, 1, 2]) === true; 

你可以说“ 但是比较string要快得多 – 没有循环… ”,那么你应该注意到有循环。 首先将数组转换为string的recursion循环,然后比较两个string。 所以这个方法比使用string更快

我相信大量的数据应该总是存储在数组中,而不是存储在对象中。 但是,如果您使用对象,也可以部分比较。
就是这样:

比较对象:

我已经说过,两个对象实例永远不会相同,即使它们现在包含相同的数据:

 ({a:1, foo:"bar", numberOfTheBeast: 666}) == ({a:1, foo:"bar", numberOfTheBeast: 666}) //false 

这有一个原因,因为可能有,例如对象内的私人variables。

但是,如果您只是使用对象结构来包含数据,则仍然可以进行比较:

 Object.prototype.equals = function(object2) { //For the first loop, we only check for types for (propName in this) { //Check for inherited methods and properties - like .equals itself //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty //Return false if the return value is different if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) { return false; } //Check instance type else if (typeof this[propName] != typeof object2[propName]) { //Different types => not equal return false; } } //Now a deeper check using other objects property names for(propName in object2) { //We must check instances anyway, there may be a property that only exists in object2 //I wonder, if remembering the checked values from the first loop would be faster or not if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) { return false; } else if (typeof this[propName] != typeof object2[propName]) { return false; } //If the property is inherited, do not check any more (it must be equa if both objects inherit it) if(!this.hasOwnProperty(propName)) continue; //Now the detail check and recursion //This returns the script back to the array comparing /**REQUIRES Array.equals**/ if (this[propName] instanceof Array && object2[propName] instanceof Array) { // recurse into the nested arrays if (!this[propName].equals(object2[propName])) return false; } else if (this[propName] instanceof Object && object2[propName] instanceof Object) { // recurse into another objects //console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\""); if (!this[propName].equals(object2[propName])) return false; } //Normal value comparison for strings and numbers else if(this[propName] != object2[propName]) { return false; } } //If everything passed, let's say YES return true; } 

但是,请记住,这是比较JSON数据,而不是类实例和其他东西。 如果你想比较复杂的对象,看看这个答案,这是超长的function 。
要使用Array.equals这个工作,你必须编辑一些原始函数:

 ... // Check if we have nested arrays if (this[i] instanceof Array && array[i] instanceof Array) { // recurse into the nested arrays if (!this[i].equals(array[i])) return false; } /**REQUIRES OBJECT COMPARE**/ else if (this[i] instanceof Object && array[i] instanceof Object) { // recurse into another objects //console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\""); if (!this[i].equals(array[i])) return false; } else if (this[i] != array[i]) { ... 

我为这两个function做了一个小testing工具 。

奖金:与indexOfcontains嵌套数组

Samy Bencherif已经为你在嵌套数组中search特定对象的情况准备了有用的函数,这些数据可以在这里find: https : //jsfiddle.net/SamyBencherif/8352y6yw/

虽然这只适用于标量数组,但它很简短:

 a1.length==a2.length && a1.every(function(v,i) { return v === a2[i]}) 

或者,在带有箭头function的ECMAScript 6 / CoffeeScript / TypeScript中:

 a1.length==a2.length && a1.every((v,i)=> v === a2[i]) 

我喜欢在Underscore和Lodash中使用Underscore库进行数组/对象重编码项目…无论您是比较数组还是对象,只是看起来像这样:

 _.isEqual(array1, array2) // returns a boolean _.isEqual(object1, object2) // returns a boolean 
  • 下划线isEqual文档
  • Lodash isEqual文档

目前还不清楚“相同”是什么意思。 例如,下面的数组ab相同(注意嵌套数组)?

 var a = ["foo", ["bar"]], b = ["foo", ["bar"]]; 

下面是一个优化的数组比较函数,该函数依次比较每个数组的相应元素,使用严格的等式进行比较,并不对数组元素本身进行recursion比较,这意味着对于上面的例子, arraysIdentical(a, b)将返回false 。 它在一般情况下工作,基于JSON和join()的解决scheme不会:

 function arraysIdentical(a, b) { var i = a.length; if (i != b.length) return false; while (i--) { if (a[i] !== b[i]) return false; } return true; }; 

我认为这是使用JSON stringify最简单的方法,在某些情况下它可能是最好的解决scheme:

 JSON.stringify(a1) === JSON.stringify(a2); 

这将对象a1a2转换为string,以便进行比较。 在大多数情况下,顺序非常重要,因为可以使用上述答案中显示的sortingalgorithm对对象进行sorting。

请注意,您不再比较对象,而是对象的string表示forms。 这可能不完全是你想要的。

build立关于TomášZato的回答,我同意只是遍历数组是最快的。 另外(就像其他人已经说过的),函数应该被称为等于/不等于。 鉴于此,我修改了函数来处理比较数组的相似性 – 即它们具有相同的元素,但是失序 – 供个人使用,并且认为我将它放在这里供大家看。

 Array.prototype.equals = function (array, strict) { if (!array) return false; if (arguments.length == 1) strict = true; if (this.length != array.length) return false; for (var i = 0; i < this.length; i++) { if (this[i] instanceof Array && array[i] instanceof Array) { if (!this[i].equals(array[i], strict)) return false; } else if (strict && this[i] != array[i]) { return false; } else if (!strict) { return this.sort().equals(array.sort(), true); } } return true; } 

该函数采用严格的附加参数,默认为true。 这个严格的参数定义了数组是否需要在内容和内容的顺序上完全相等,或者仅仅包含相同的内容。

例:

 var arr1 = [1, 2, 3, 4]; var arr2 = [2, 1, 4, 3]; // Loosely equal to 1 var arr3 = [2, 2, 3, 4]; // Not equal to 1 var arr4 = [1, 2, 3, 4]; // Strictly equal to 1 arr1.equals(arr2); // false arr1.equals(arr2, false); // true arr1.equals(arr3); // false arr1.equals(arr3, false); // false arr1.equals(arr4); // true arr1.equals(arr4, false); // true 

我也写了一个快速jsfiddle的function和这个例子:
http://jsfiddle.net/Roundaround/DLkxX/

实用的方法

我认为如果一个特定的实现是“正确的方法”,如果它只是“正确”(“正确的”)而不是“错误的”解决scheme是错误的。 对于基于string的数组比较,Tomáš的解决scheme是一个明显的改进,但这并不意味着它是客观的“正确的”。 什么是正确的呢? 这是最快的吗? 这是最灵活的吗? 这是最容易理解的吗? debugging最快吗? 它使用最less的操作? 有没有副作用? 没有一个解决scheme可以拥有所有的最好的东西。

Tomáš可以说他的解决scheme很快,但我也会说这是不必要的复杂。 它试图成为一个全function于一身的解决scheme,适用于所有嵌套或不嵌套的数组。 事实上,它甚至接受的不仅仅是数组作为input,而且还试图给出一个“有效”的答案。


generics提供了可重用性

我的回答会以不同的方式解决问题。 我将从一个通用的arrayCompare过程开始,这个过程只关心数组的步骤。 从那里,我们将build立我们的其他基本的比较函数,如arrayEqualarrayDeepEqual

 // arrayCompare :: (a -> a -> Bool) -> [a] -> [a] -> Bool const arrayCompare = f=> ([x,...xs]) => ([y,...ys]) => { if (x === undefined && y === undefined) return true else if (! f (x) (y)) return false else return arrayCompare (f) (xs) (ys) } 

在我看来,最好的代码甚至不需要评论,这也不例外。 这里发生的事情很less,几乎可以毫不费力地理解这个过程的行为。 当然,现在有一些ES6语法对你来说可能是陌生的,但这只是因为ES6是相对较新的。

正如types所暗示的, arrayCompare比较函数f和两个input数组xsys 。 在大多数情况下,我们所做的就是对input数组中的每个元素调用f (x) (y) 。 如果用户定义的f返回false返回一个false 。 所以是的,这意味着比较器可以提前停止迭代,并防止不必要的循环通过input数组的其余部分。


严格比较

接下来,使用我们的arrayCompare函数,我们可以很容易地创build我们可能需要的其他函数。 我们将从基本arrayEqual开始

 // equal :: a -> a -> Bool const equal = x => y => x === y // arrayEqual :: [a] -> [a] -> Bool const arrayEqual = arrayCompare (equal) let xs = [1,2,3] let ys = [1,2,3] console.log(arrayEqual (xs) (ys)) //=> true // (1 === 1) && (2 === 2) && (3 === 3) //=> true let zs = ['1','2','3'] console.log(arrayEqual (xs) (zs)) //=> false // (1 === '1') //=> false 

就那么简单。 arrayEqual可以使用arrayCompare定义,比较器函数使用===比较ab (严格相等)。

注意,我们也定义了它自己的function。 这突出了arrayCompare作为一个高阶函数在另一个数据types(Array)的上下文中利用我们的一阶比较器的作用。


松散的比较

我们可以使用a ==轻松定义arrayLooseEqual 。 现在比较1 (数字)和'1' (string),结果将是true

 // looseEqual :: a -> a -> Bool const looseEqual = x => y => x == y // arrayLooseEqual :: [a] -> [a] -> Bool const arrayLooseEqual = arrayCompare (looseEqual) let xs = [1,2,3] let ys = ['1','2','3'] console.log(arrayLooseEqual (xs) (ys)) //=> true // (1 == '1') && (2 == '2') && (3 == '3') //=> true 

深入比较(recursion)

你可能已经注意到,这只是浅薄的比较。 当然,Tomáš的解决scheme是“正确的方法”,因为它隐含深入的比较,对吧?

那么我们的arrayCompare程序是多才多艺的足够使用的方式,使深入的平等testing轻而易举…

 // isArray :: a -> Bool const isArray = Array.isArray // arrayDeepCompare :: (a -> a -> Bool) -> [a] -> [a] -> Bool const arrayDeepCompare = f => arrayCompare (a => b => { if (isArray(a) && isArray(b)) return arrayDeepCompare (f) (a) (b) else return f (a) (b) }) let xs = [1,[2,[3]]] let ys = [1,[2,['3']]] console.log(arrayDeepCompare (equal) (xs) (ys)) //=> false // (1 === 1) && (2 === 2) && (3 === 3) //=> false console.log(arrayDeepCompare (looseEqual) (xs) (ys)) //=> true // (1 == 1) && (2 == 2) && (3 == '3') //=> true 

就那么简单。 我们使用另一个更高阶的函数来构build深度比较器。 这次我们使用自定义的比较器来包装arrayCompare ,它将检查ab是否是数组。 如果是这样,则重新应用arrayDeepCompare否则将ab与用户指定的比较器( f )进行比较。 这使我们能够将深度比较行为与实际比较各个元素的方式分开。 也就是说,就像上面的例子所显示的那样,我们可以使用equallooseEqual或者我们所做的任何其他比较器进行深入比较。

因为arrayDeepCompare是curry的,所以我们可以像前面的例子那样部分地应用它

 // arrayDeepEqual :: [a] -> [a] -> Bool const arrayDeepEqual = arrayDeepCompare (equal) // arrayDeepLooseEqual :: [a] -> [a] -> Bool const arrayDeepLooseEqual = arrayDeepCompare (looseEqual) 

对我来说,这已经是对Tomáš解决scheme的明显改进,因为我可以根据需要明确地select浅层或深层比较。


对象比较(示例)

现在,如果你有一个对象或东西的数组呢? 如果每个对象具有相同的id值,也许你想把这些数组视为“相等”…

 // idEqual :: {id: Number} -> {id: Number} -> Bool const idEqual = x => y => x.id !== undefined && x.id === y.id // arrayIdEqual :: [a] -> [a] -> Bool const arrayIdEqual = arrayCompare (idEqual) let xs = [{id:1},{id:2}] let ys = [{id:1},{id:2}] console.log(arrayIdEqual (xs) (ys)) //=> true // (1 === 1) && (2 === 2) //=> true let zs = [{id:1},{id:6}] console.log(arrayIdEqual (xs) (zs)) //=> false // (1 === 1) && (2 === 6) //=> false 

就那么简单。 在这里我使用了vanilla JS对象,但是这种types的比较器可以用于任何对象types。 甚至你的自定义对象。 为了支持这种平等testing,Tomáš的解决scheme需要完全重新devise

与对象深度arrays? 不是问题。 我们构build了高度通用的通用函数,所以它们将在各种各样的用例中工作。

 let xs = [{id:1},[{id:2}]] let ys = [{id:1},[{id:2}]] console.log(arrayCompare (idEqual) (xs) (ys)) //=> false console.log(arrayDeepCompare (idEqual) (xs) (ys)) //=> true 

任意比较(示例)

或者如果你想做一些其他types的完全武断的比较呢? 也许我想知道,如果每个x比每个y更大…

 // gt :: Number -> Number -> Bool const gt = x => y => x > y // arrayGt :: [a] -> [a] -> Bool const arrayGt = arrayCompare (gt) let xs = [5,10,20] let ys = [2,4,8] console.log(arrayGt (xs) (ys)) //=> true // (5 > 2) && (10 > 4) && (20 > 8) //=> true let zs = [6,12,24] console.log(arrayGt (xs) (zs)) //=> false // (5 > 6) //=> false 

less即是多

你可以看到我们实际上用更less的代码来做更多的事情。 arrayCompare本身没有什么复杂的,我们所做的每个自定义比较器都有一个非常简单的实现。

轻松地,我们可以准确定义我们希望如何比较两个数组 – 浅,深,严格,松散,某些对象属性或某些任意计算或这些的任意组合 – 都使用一个过程 arrayCompare 。 也许甚至梦想一个RegExp比较器! 我知道孩子们如何喜欢这些正则expression式

这是最快的吗? 不。 但它可能并不需要。 如果速度是衡量代码质量的唯一标准,那么很多真正优秀的代码将被抛弃 – 这就是为什么我将这种方法称为实用方法 。 或者也许更公平一个实用的方法。 这个描述适合这个答案,因为我不是说这个答案只是比较其他答案的实际; 客观上是对的。 我们已经达到了高度的实用性,很less有代码很容易推理。 没有其他的代码可以说我们还没有赢得这个描述。

这是否使它成为您的“正确”解决scheme? 这是自己决定的。 没有人能为你做这件事。 只有你知道你的需求是什么。 在几乎所有情况下,我都非常看重直接,实用,多function的代码。 你的价值可能不同,所以select适合你的东西。


编辑

我以前的答案更关注于将arrayEqual分解成小程序。 这是一个有趣的练习,但并不是解决这个问题最好的(最实际的)方法。 如果你有兴趣,你可以看到这个修订历史。

本着原始问题的精神:

我想比较两个arrays…理想, 有效没有什么幻想 ,只要它们是相同的就是真实的,假如没有 ,就是假的。

我一直在对这里提出的一些更简单的build议进行性能testing, 结果如下(快到慢):

Tim Down的(67%)

 var i = a1.length; while (i--) { if (a1[i] !== a2[i]) return false; } return true 

每 (69%)由user2782196

 a1.every((v,i)=> v === a2[i]); 

减less (74%) DEIs

 a1.reduce((a, b) => a && a2.includes(b), true); 

join & toString (78%)通过Gaizka Allende&vivek

 a1.join('') === a2.join(''); a1.toString() === a2.toString(); 

一半toString (90%) Victor Palomo

 a1 == a2.toString(); 

串起(100%) radtek

 JSON.stringify(a1) === JSON.stringify(a2); 

注意下面的例子假定数组是sorting的一维数组。 .length比较已经被删除了一个共同的基准(添加a1.length === a2.length任何的build议,你会得到〜10%的性能提升)。 select最适合您的解决scheme,了解每个解决scheme的速度和限制。

无关的注释:很有趣的是,看到人们在这个问题的完全合法的答案上得到所有触发约翰·韦恩(John Waynes)的投票button。

与JSON.encode相同的是使用join()。

 function checkArrays( arrA, arrB ){ //check if lengths are different if(arrA.length !== arrB.length) return false; //slice so we do not effect the original //sort makes sure they are in order //join makes it a string so we can do a string compare var cA = arrA.slice().sort().join(","); var cB = arrB.slice().sort().join(","); return cA===cB; } var a = [1,2,3,4,5]; var b = [5,4,3,2,1]; var c = [1,2,3,4]; var d = [1,2,3,4,6]; var e = ["1","2","3","4","5"]; //will return true console.log( checkArrays(a,b) ); //true console.log( checkArrays(a,c) ); //false console.log( checkArrays(a,d) ); //false console.log( checkArrays(a,e) ); //true 

唯一的问题是如果你关心上次比较testing的types。 如果你关心types,你将不得不循环。

 function checkArrays( arrA, arrB ){ //check if lengths are different if(arrA.length !== arrB.length) return false; //slice so we do not effect the orginal //sort makes sure they are in order var cA = arrA.slice().sort(); var cB = arrB.slice().sort(); for(var i=0;i<cA.length;i++){ if(cA[i]!==cB[i]) return false; } return true; } var a = [1,2,3,4,5]; var b = [5,4,3,2,1]; var c = [1,2,3,4]; var d = [1,2,3,4,6]; var e = ["1","2","3","4","5"]; console.log( checkArrays(a,b) ); //true console.log( checkArrays(a,c) ); //false console.log( checkArrays(a,d) ); //false console.log( checkArrays(a,e) ); //false 

如果顺序应该保持不变,那只是一个循环,不需要sorting。

 function checkArrays( arrA, arrB ){ //check if lengths are different if(arrA.length !== arrB.length) return false; for(var i=0;i<arrA.length;i++){ if(arrA[i]!==arrB[i]) return false; } return true; } var a = [1,2,3,4,5]; var b = [5,4,3,2,1]; var c = [1,2,3,4]; var d = [1,2,3,4,6]; var e = ["1","2","3","4","5"]; console.log( checkArrays(a,a) ); //true console.log( checkArrays(a,b) ); //false console.log( checkArrays(a,c) ); //false console.log( checkArrays(a,d) ); //false console.log( checkArrays(a,e) ); //false 

对于单维数组,你可以简单地使用:

arr1.sort().toString() == arr2.sort().toString()

这也将照顾索引不匹配的数组。

如果您正在使用像Chaocha断言库一样的Mochatesting框架,则可以使用深度相等来比较数组。

 expect(a1).to.deep.equal(a2) 

只有当数组在相应的索引处具有相同的元素时,这应该返回true。

Herer的我的解决scheme:

 /** * Tests two data structures for equality * @param {object} x * @param {object} y * @returns {boolean} */ var equal = function(x, y) { if (typeof x !== typeof y) return false; if (x instanceof Array && y instanceof Array && x.length !== y.length) return false; if (typeof x === 'object') { for (var p in x) if (x.hasOwnProperty(p)) { if (typeof x[p] === 'function' && typeof y[p] === 'function') continue; if (x[p] instanceof Array && y[p] instanceof Array && x[p].length !== y[p].length) return false; if (typeof x[p] !== typeof y[p]) return false; if (typeof x[p] === 'object' && typeof y[p] === 'object') { if (!equal(x[p], y[p])) return false; } else if (x[p] !== y[p]) return false; } } else return x === y; return true; }; 

适用于任何嵌套的数据结构,显然会忽略对象的方法。 甚至不想用这种方法来扩展Object.prototype,当我试过这个,jQuery破了;)

对于大多数arrays来说,它比大多数序列化解决scheme还要快。 这可能是对象logging数组最快的比较方法。

我们可以通过函数的方式来实现,使用( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/every

 function compareArrays(array1, array2) { if (array1.length === array2.length) return array1.every((a, index) => a === array2[index]) else return false } // test var a1 = [1,2,3]; var a2 = [1,2,3]; var a3 = ['a', 'r', 'r', 'a', 'y', '1'] var a4 = ['a', 'r', 'r', 'a', 'y', '2'] console.log(compareArrays(a1,a2)) // true console.log(compareArrays(a1,a3)) // false console.log(compareArrays(a3,a4)) // false 

This compares 2 unsorted arrays:

 function areEqual(a, b) { if ( a.length != b.length) { return false; } return a.filter(function(i) { return !b.includes(i); }).length === 0; } 

If they are two arrays of numbers or strings only, this is a quick one-line one

 const array1 = [1, 2, 3]; const array2 = [1, 3, 4]; console.log(array1.join(',') === array2.join(',')) //false const array3 = [1, 2, 3]; const array4 = [1, 2, 3]; console.log(array3.join(',') === array4.join(',')) //true 

this script compares Object, Arrays and multidimensional array

 function compare(a,b){ var primitive=['string','number','boolean']; if(primitive.indexOf(typeof a)!==-1 && primitive.indexOf(typeof a)===primitive.indexOf(typeof b))return a===b; if(typeof a!==typeof b || a.length!==b.length)return false; for(i in a){ if(!compare(a[i],b[i]))return false; } return true; } 

first line checks whether it's a primitive type. if so it compares the two parameters.

if they are Objects. it iterates over the Object and check every element recursivly.

用法:

 var a=[1,2,[1,2]]; var b=[1,2,[1,2]]; var isEqual=compare(a,b); //true 

This function compares two arrays of arbitrary shape and dimesionality:

 function equals(a1, a2) { if (!Array.isArray(a1) || !Array.isArray(a2)) { throw new Error("Arguments to function equals(a1, a2) must be arrays."); } if (a1.length !== a2.length) { return false; } for (var i=0; i<a1.length; i++) { if (Array.isArray(a1[i]) && Array.isArray(a2[i])) { if (equals(a1[i], a2[i])) { continue; } else { return false; } } else { if (a1[i] !== a2[i]) { return false; } } } return true; } 

The reason is that identity or strict operator (===), it compares with no type conversion, that means if both values doesn't have the same value and the same type, they won't be considered equal.

take a look this link, it takes you out of doubt easy way to understand how identity operator works

 var a1 = [1,2,3,6]; var a2 = [1,2,3,5]; function check(a, b) { return (a.length != b.length) ? false : a.every(function(row, index) { return a[index] == b[index]; }); } check(a1, a2); 

////// OR ///////

 var a1 = [1,2,3,6]; var a2 = [1,2,3,6]; function check(a, b) { return (a.length != b.length) ? false : !(a.some(function(row, index) { return a[index] != b[index]; })); } check(a1, a2) 

Choose each from [a] and loop through all from [b]: Result: 1, 5

 var a = [1,4,5,9]; var b = [1,6,7,5]; for (i = 0; i < a.length; i++) { for (z = 0; z < a.length; z++) { if (a[i] === b[z]) { console.log(b[z]); // if match > console.log it } } } 

Even though this has a lot of answers, one that I believe to be of help:

 const newArray = [ ...new Set( [...arr1, ...arr2] ) ] 

It is not stated in the question how the structure of the array is going to look like, so If you know for sure that you won't have nested arrays nor objects in you array (it happened to me, that's why I came to this answer) the above code will work.

What happens is that we use spread operator ( … ) to concat both arrays, then we use Set to eliminate any duplicates. Once you have that you can compare their sizes, if all three arrays have the same size you are good to go.

This answer also ignores the order of elements , as I said, the exact situation happened to me, so maybe someone in the same situation might end up here (as I did).


Edit1.

Answering Dmitry Grinko's question: "Why did you use spread operator ( … ) here – …new Set ? It doesn't work"

考虑这个代码:

 const arr1 = [ 'a', 'b' ] const arr2 = [ 'a', 'b', 'c' ] const newArray = [ new Set( [...arr1, ...arr2] ) ] console.log(newArray) 

You'll get

 [ Set { 'a', 'b', 'c' } ] 

In order to work with that value you'd need to use some Set properties (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set ). On the other hand, when you use this code:

 const arr1 = [ 'a', 'b' ] const arr2 = [ 'a', 'b', 'c' ] const newArray = [ ...new Set( [...arr1, ...arr2] ) ] console.log(newArray) 

You'll get

 [ 'a', 'b', 'c' ] 

That's the difference, the former would give me a Set, it would work too as I could get the size of that Set, but the latter gives me the array I need, what's more direct to the resolution.

Extending Tomáš Zato idea. Tomas's Array.prototype.compare should be infact called Array.prototype.compareIdentical.

It passes on:

 [1, 2, [3, 4]].compareIdentical ([1, 2, [3, 2]]) === false; [1, "2,3"].compareIdentical ([1, 2, 3]) === false; [1, 2, [3, 4]].compareIdentical ([1, 2, [3, 4]]) === true; [1, 2, 1, 2].compareIdentical ([1, 2, 1, 2]) === true; 

But fails on:

 [[1, 2, [3, 2]],1, 2, [3, 2]].compareIdentical([1, 2, [3, 2],[1, 2, [3, 2]]]) 

Here is better (in my opinion) version:

 Array.prototype.compare = function (array) { // if the other array is a falsy value, return if (!array) return false; // compare lengths - can save a lot of time if (this.length != array.length) return false; this.sort(); array.sort(); for (var i = 0; i < this.length; i++) { // Check if we have nested arrays if (this[i] instanceof Array && array[i] instanceof Array) { // recurse into the nested arrays if (!this[i].compare(array[i])) return false; } else if (this[i] != array[i]) { // Warning - two different object instances will never be equal: {x:20} != {x:20} return false; } } return true; } 

http://jsfiddle.net/igos/bcfCY/

My solution compares Objects, not Arrays. This would work in the same way as Tomáš's as Arrays are Objects, but without the Warning:

 Object.prototype.compare_to = function(comparable){ // Is the value being compared an object if(comparable instanceof Object){ // Count the amount of properties in @comparable var count_of_comparable = 0; for(p in comparable) count_of_comparable++; // Loop through all the properties in @this for(property in this){ // Decrements once for every property in @this count_of_comparable--; // Prevents an infinite loop if(property != "compare_to"){ // Is the property in @comparable if(property in comparable){ // Is the property also an Object if(this[property] instanceof Object){ // Compare the properties if yes if(!(this[property].compare_to(comparable[property]))){ // Return false if the Object properties don't match return false; } // Are the values unequal } else if(this[property] !== comparable[property]){ // Return false if they are unequal return false; } } else { // Return false if the property is not in the object being compared return false; } } } } else { // Return false if the value is anything other than an object return false; } // Return true if their are as many properties in the comparable object as @this return count_of_comparable == 0; } 

Hope this helps you or anyone else searching for an answer.

 function compareArrays(arrayA, arrayB) { if (arrayA.length != arrayB.length) return true; for (i = 0; i < arrayA.length; i++) if (arrayB.indexOf(arrayA[i]) == -1) { return true; } } for (i = 0; i < arrayB.length; i++) { if (arrayA.indexOf(arrayB[i]) == -1) { return true; } } return false; } 

If the array is plain and the order is matter so this two lines may help

 //Assume var a = ['a','b', 'c']; var b = ['a','e', 'c']; if(a.length !== b.length) return false; return !a.reduce( function(prev,next,idx, arr){ return prev || next != b[idx] },false ); 

Reduce walks through one of array and returns 'false' if at least one element of 'a' is nor equial to element of 'b' Just wrap this into function

Here's a CoffeeScript version, for those who prefer that:

 Array.prototype.equals = (array) -> return false if not array # if the other array is a falsy value, return return false if @length isnt array.length # compare lengths - can save a lot of time for item, index in @ if item instanceof Array and array[index] instanceof Array # Check if we have nested arrays if not item.equals(array[index]) # recurse into the nested arrays return false else if this[index] != array[index] return false # Warning - two different object instances will never be equal: {x:20} != {x:20} true 

All credits goes to @tomas-zato.

In my case compared arrays contain only numbers and strings. This function will show you if arrays contain same elements.

 function are_arrs_match(arr1, arr2){ return arr1.sort().toString() === arr2.sort().toString() } 

Let's test it!

 arr1 = [1, 2, 3, 'nik'] arr2 = ['nik', 3, 1, 2] arr3 = [1, 2, 5] console.log (are_arrs_match(arr1, arr2)) //true console.log (are_arrs_match(arr1, arr3)) //false 

While the top answer to this question is correct and good, the code provided could use some improvement.

Below is my own code for comparing arrays and objects. The code is short and simple:

 Array.prototype.equals = function(otherArray) { if (!otherArray || this.length != otherArray.length) return false; return this.reduce(function(equal, item, index) { var otherItem = otherArray[index]; var itemType = typeof item, otherItemType = typeof otherItem; if (itemType !== otherItemType) return false; return equal && (itemType === "object" ? item.equals(otherItem) : item === otherItem); }, true); }; if(!Object.prototype.keys) { Object.prototype.keys = function() { var a = []; for (var key in this) { if (this.hasOwnProperty(key)) a.push(key); } return a; } Object.defineProperty(Object.prototype, "keys", {enumerable: false}); } Object.prototype.equals = function(otherObject) { if (!otherObject) return false; var object = this, objectKeys = object.keys(); if (!objectKeys.equals(otherObject.keys())) return false; return objectKeys.reduce(function(equal, key) { var value = object[key], otherValue = otherObject[key]; var valueType = typeof value, otherValueType = typeof otherValue; if (valueType !== otherValueType) return false; // this will call Array.prototype.equals for arrays and Object.prototype.equals for objects return equal && (valueType === "object" ? value.equals(otherValue) : value === otherValue); }, true); } Object.defineProperty(Object.prototype, "equals", {enumerable: false}); 

This code supports arrays nested in objects and objects nested in arrays.

You can see a full suite of tests and test the code yourself at this repl: https://repl.it/Esfz/3

tried deep-equal and it worked

 var eq = require('deep-equal'); eq({a: 1, b: 2, c: [3, 4]}, {c: [3, 4], a: 1, b: 2}); 

Another approach with very few code (using Array reduce and Array includes ):

 arr1.length == arr2.length && arr1.reduce((a, b) => a && arr2.includes(b), true) 

If you want to compare also the equality of order:

 arr1.length == arr2.length && arr1.reduce((a, b, i) => a && arr2[i], true) 
  • The length check ensures that the set of elements in one array isn't just a subset of the other one.

  • The reducer is used to walk through one array and search for each item in other array. If one item isn't found the reduce function returns false .

    1. In the first example it's being tested that an element is included
    2. The second example check for the order too