Using lodash to compare arrays (items exist without an order)

I know I can do this with loops, but I'm trying to find an elegant way to do this:

I have two arrays:

var array1 = [['a', 'b'], ['b', 'c']]; var array2 = [['b', 'c'], ['a', 'b']]; 

I want to use lodash to confirm that both are the same. By "the same" I mean that in array 1 there is no element that is not contained in array2.

In terms of checking equality between these elements:

 ['a', 'b'] == ['b', 'a'] 

or

 ['a', 'b'] == ['a', 'b'] 

both work as letters will always be in order.

Thanks in advance.

+91
javascript arrays lodash
Apr 29 '15 at 18:08
source share
7 answers

If you are sorting an external array, you can use _.isEqual() since the internal array is already sorted.

 var array1 = [['a', 'b'], ['b', 'c']]; var array2 = [['b', 'c'], ['a', 'b']]; _.isEqual(array1.sort(), array2.sort()); //true 

Note that .sort() will mutate arrays. If this is a problem for you, first make a copy using (for example) .slice() or the distribution operator ( ... ).

Or do as Daniel Budik recommends in the comment below:

 _.isEqual(_.sortBy(array1), _.sortBy(array2)) 

Lodash sortBy() will not modify the array.

+174
Apr 29 '15 at 18:13
source share

You can use lodashs xor for this

 doArraysContainSameElements = _.xor(arr1, arr2).length === 0 
+15
Feb 20 '19 at 14:27
source share

By "the same" I mean that in array 1 there is no element that is not contained in the array.

For this you can use flatten () and difference (), which works well if you don't care if there are elements in array2 that are not in array1 . It looks like you are asking: array1 is a subset of array2?

 var array1 = [['a', 'b'], ['b', 'c']]; var array2 = [['b', 'c'], ['a', 'b']]; function isSubset(source, target) { return !_.difference(_.flatten(source), _.flatten(target)).length; } isSubset(array1, array2); // → true array1.push('d'); isSubset(array1, array2); // → false isSubset(array2, array1); // → true 
+6
Apr 29 '15 at 18:44
source share

I know you didn’t want to repeat myself, but this is a pretty simple IMO

 const arr1 = ["a", "b"]; const arr2 = ["b", "a"]; const equal = arr1.every(item => arr2.includes(item)); console.log(equal) // true 
+2
Oct 16 '18 at 21:26
source share

We can use the _.difference function to see if there is a difference or not.

 function isSame(arrayOne, arrayTwo) { var a = arrayOne, b = arrayTwo; if (arrayOne.length <= arrayTwo.length) { a = arrayTwo; b = arrayOne; return _.isEmpty(_.difference(a.sort(), b.sort())); } else { return false; } } // examples console.log(isSame([1, 2, 3], [1, 2, 3])); // true console.log(isSame([1, 2, 4], [1, 2, 3])); // false console.log(isSame([1, 2], [2, 3, 1])); // false console.log(isSame([2, 3, 1], [1, 2])); // false 

I hope this helps you.

+1
Dec 08 '16 at 5:04 on
source share

PURE JS (also works when arrays and subarrays have more than 2 elements in random order). If the string contains,, use join('-') as the character parameter (maybe utf), which is not used in strings

 array1.map(x=>x.sort()).sort().join() === array2.map(x=>x.sort()).sort().join() 

 var array1 = [['a', 'b'], ['b', 'c']]; var array2 = [['b', 'c'], ['b', 'a']]; var r = array1.map(x=>x.sort()).sort().join() === array2.map(x=>x.sort()).sort().join(); console.log(r); 

+1
Dec 18 '18 at 16:36
source share

There are already answers here, but here is my pure JS implementation. I’m not sure if it’s optimal, but it is transparent, readable and simple.

 // Does array a contain elements of array b? const contains = (a, b) => new Set([...a, ...b]).size === a.length const isEqualSet = (a, b) => contains(a, b) && contains(b, a) 

The rationale for contains() is that if a contains all the elements of b , then putting them in the same set will not result in a resize.

For example, if const a = [1,2,3,4] and const b = [1,2] , then new Set([...a, ...b]) === {1,2,3,4} . As you can see, the result set has the same elements as a .

From there, to make it more concise, we can reduce it to the following:

 const isEqualSet = (a, b) => { const unionSize = new Set([...a, ...b]) return unionSize === a.length && unionSize === b.length } 
+1
Sep 19 '19 at 19:49
source share



All Articles