How to know if two arrays have the same values
Asked Answered
G

33

191

I have these two arrays: one is filled with information from an ajax request and another stores the buttons the user clicks on. I use this code (I filled with sample numbers):

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();
}

But it always gives false, even if the two arrays are the same, but with different name. (I checked this in Chrome's JS Console). So, is there any way I could know if these two arrays contain the same? Why is it giving false? How can I know which values in the first array are not in the second?

Geometrid answered 3/6, 2011 at 15:32 Comment(4)
I am pretty certain you need to go through each element of the arrays.Bihar
Do you know why it returns false? Curious.Restraint
See @Andrew 's answer https://mcmap.net/q/134552/-how-to-know-if-two-arrays-have-the-same-valuesGeometrid
possible duplicate of how to check javascript array equals?Cru
A
59

Sort the arrays and compare their values one by one.

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;
}
Apocryphal answered 18/4, 2017 at 17:17 Comment(8)
sorting takes nlog(n) time. You don't need sorting. This answer https://mcmap.net/q/134552/-how-to-know-if-two-arrays-have-the-same-values works in linear time.Presurmise
Using typescript the Array.isArray() was causing errors, removing that it worked fine.Laynelayney
@Presurmise the function from link return true when arrays are: [1,2] and [1,1,2] in my case, these are 2 different arrays. While this function says false to these 2 different arrays.Garage
@LukasLiesis the question asks "if two arrays have the same values". So it is not asking whether they are the same or not. I understood that it's asking whether arrays are equal sets or not. en.wikipedia.org/wiki/Set_(mathematics). [1,2] and [1,1,2] are equal sets. They all contain 1 and 2Presurmise
@Presurmise dont be silly, OP explicitly noted that they are same elements but may be in different order because of user inputVictorie
It won't work with [1, 2, 3] and [3, 4, 5].Halliehallman
@YevheniiShlapak because these arrays share only 1 value ...Apocryphal
@canbax: The answer you link to may not be the correct answer for OP here, but it is perfect match for my use case :)Sargent
H
161

If your array items are not objects- if they are numbers or strings, for example, you can compare their joined strings to see if they have the same members in any order-

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');
Hexastyle answered 3/6, 2011 at 17:6 Comment(8)
This will work well for primitives or objects that have uniquely identifying toString values, but not for just any objects.Mannered
Beware of null items and sorting. I ended up in my case with strings to compare like ",2,2,3" and "2,2,3," which of course aren't strictly equal.Bludge
Could fail for strings, i.e. ['a', 'b'] and ['a,b']. I would only recommend this technique for small throwaway scripts.Underdone
Hi kennebec, can you tell how to save matched into another arrayAgouti
One downside is that the sorting is done in place. You may want to compare whether two arrays have the same values without sorting the arrays in place.Servia
@Underdone -- in my case, commas are allowed in strings but semi colons aren't, so I used ';' to join instead of commaBuxtehude
This is horrible. Up to 1000x slower than any other method.Scrod
this is too expensive, like wayyyy too expensive.Boxwood
C
69

If you want to check only if two arrays have same values (regardless the number of occurrences and order of each value) you could do this by using lodash:

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

Short, simple and pretty!

Cataclysmic answered 7/1, 2015 at 10:25 Comment(3)
I cannot seem to find xor in the underscore docs? Are you thinking of IODash?Palomino
This only works with integers. The question was "two arrays" not "two arrays of integers"Scrod
Yep. In 2021 and confirming it works with arrays of strings. :-)Freemanfreemartin
A
59

Sort the arrays and compare their values one by one.

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;
}
Apocryphal answered 18/4, 2017 at 17:17 Comment(8)
sorting takes nlog(n) time. You don't need sorting. This answer https://mcmap.net/q/134552/-how-to-know-if-two-arrays-have-the-same-values works in linear time.Presurmise
Using typescript the Array.isArray() was causing errors, removing that it worked fine.Laynelayney
@Presurmise the function from link return true when arrays are: [1,2] and [1,1,2] in my case, these are 2 different arrays. While this function says false to these 2 different arrays.Garage
@LukasLiesis the question asks "if two arrays have the same values". So it is not asking whether they are the same or not. I understood that it's asking whether arrays are equal sets or not. en.wikipedia.org/wiki/Set_(mathematics). [1,2] and [1,1,2] are equal sets. They all contain 1 and 2Presurmise
@Presurmise dont be silly, OP explicitly noted that they are same elements but may be in different order because of user inputVictorie
It won't work with [1, 2, 3] and [3, 4, 5].Halliehallman
@YevheniiShlapak because these arrays share only 1 value ...Apocryphal
@canbax: The answer you link to may not be the correct answer for OP here, but it is perfect match for my use case :)Sargent
F
51

Why your code didn't work

In JavaScript, for non-primitive data types like arrays, == and === check for reference equality (leaving aside type conversions that == may perform). That is, they check whether arr1 and arr2 are the same object in memory. In your example, the two arrays have the same elements in the same order, but are not equal.

Here's an example that hopefully builds the intuition that false is the right result for [1] === [1]:

const x = [1];
const y = [1];
x === y; // false
x[0] = 200;
console.log(x); // "Array [ 200 ]"
console.log(y); // "Array [ 1 ]"
x === y; // false

Solutions

Two arrays, arr1 and arr2, have the same members if and only if:

  • Everything in arr2 is in arr1

AND

  • Everything in arr1 is in arr2

So this will do the trick (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`

This second solution using Underscore is closer to what you were trying to do:

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

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

It works because isEqual checks for "deep equality," meaning it looks at more than just reference equality and compares values.

A solution to your third question

You also asked how to find out which things in arr1 are not contained in arr2.

This will do it (ES2015):

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

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

You could also use Underscore's difference: method:

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

UPDATE

See @Redu's comment—my solution is for sameMembers, but what you may have in mind is sameMembersInOrder also-known-as deepEquals.

UPDATE 2

If you don't care about the order of the members of the arrays, ES2015+'s Set may be a better data structure than Array. See the MDN notes on how to implement isSuperset and difference using dangerous monkey-patching.

Update 3

If order doesn't matter, it's still better to use sets. But if you must use arrays, this solution has better time complexity than the one I gave earlier:

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))
}
Flown answered 2/1, 2016 at 13:49 Comment(7)
Your solutions are wrong. "Two arrays, arr1 and arr2, have the same members if and only if: Everything in arr2 is in arr1 AND Everything in arr1 is in arr2" this is also wrong. This is an array not a set. So sameMembers([1,1,2],[2,1,2]);should return false.Realism
@Realism guess it depends on what "same members" means—I take it to mean "has the same members." sameMembers([1,1,2],[2,1,2]) should return true, in my opinion. sameMembersInOrder([1,1,2],[2,1,2]) AKA deepEquals([1,1,2],[2,1,2]) should return false.Flown
Your third solution arr1.filter... will only work for checking if arr2 has all the elements of arr1 or not but not the other way around which is also required.Ashlieashlin
My sack has 2 apples and 1 orange. Your sack has 2 oranges and 1 apple. They don't have the same members. [1,1,2] and [2,1,2] are not the same members..Scrod
@gman, those aren't oranges and apples, they are numbers, and 1 === 1. But it sounds like you want to check that the two arrays have the same items in the same order: in that case you'll want a different algorithm.Flown
It doesn't seem like a matter of checking the order to me, but the number of occurrences of each discrete value being the same. So sameMembers([1,1,2], [1,2,1]) should return true, and sameMembers(1,1,2],[1,2,1]) should return false. If we can know there won't be any duplicates this algorithm would work.Cushitic
@ChrisWalker I re-read the question and it looks like you're right about what OP was askingFlown
P
42
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();
}

Maybe?

Prosector answered 3/6, 2011 at 15:36 Comment(5)
Thank you! It works just as desired. I modified a little the function so I could also know how many mismatches are.Geometrid
false for [2,4] [4,2].Pottage
@SurazKhanal Still need to sortMournful
Modifying built-in types is a Bad Idea(tm).Equator
@HereticMonkey Agreed :-) (This answer is more than 10 years and does not represent good practices any longer)Prosector
P
18

Our aim is basically to check whether 2 arrays are equal sets. set is the mathematically defined set. Fastest sorting asymptotically takes O(nlog(n)) time. So If you sort an array, it would take at least O(nlog(n)) time. But you can do this task faster, which asymptotically takes O(n) time (average case not worst case) with a dictionary data structure. In JS, a dictionary is simply an object with keys and values.

/** 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;
}

Note that this function works with arrays of primitive types and assumes a1 and a2 are arrays.

Presurmise answered 10/4, 2019 at 14:8 Comment(8)
This doesn't handle the case where there are repeated values in one of the arrays. e.g. areArraysEqualSets([1, 2, 2], [1, 2])Brede
It does. I tried in the console. areArraysEqualSets([1, 2, 2], [1, 2]) true Mathmatically they are equal sets.Presurmise
This isn't an answer to the question. The question didn't ask about sets, it asked about arrays. [1,2,2], and [1,2] are not the same arrays. This answer would be deleted as "not an answer"Scrod
@Scrod You are wrong the question title is How to know if two arrays have the same values. It is not really clear about repeating values. BUT I understand that he basically asks for whether 2 arrays are equal sets. So I still think my answer is true and also the fastest working algorithm. (Didn't check the new answers after I wrote mine). Also, note that I'm not talking about the Set class in javascript. Set that I'm referring to is the theoric. It is a mathematical definition. I already give a link to what I'm referringPresurmise
Well, we can argue they we're not looking for 'same set members' based on the answer they choose. They didn't choose a 'sets' solution. As for fastest, it dependsScrod
@Scrod I think if two arrays have the same values expression is clearly asking for set equality. The author might not mean it but the expression simply says this. I don't care what they choose. They might just copy-paste the codes and upvote if it works for their particular example. (that's what we do, we should accept it ;) My answer is simply a right answer to the question.Presurmise
From the question "and another stores the buttons the user clicks on". If the user clicks "apple apple orange" they wanted 2 apples and an orange not any combination of apples and oranges.Scrod
It doesn't matter if this doesn't technically answer the question; it is still a useful answer. I searched this question for an answer exactly like this.Subnormal
F
17

What about this? ES 2017 i suppose:

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);

1st condition checks if both arrays have same length and 2nd condition checks if 1st array is a subset of the 2nd array. Combining these 2 conditions should then result in comparison of all items of the 2 arrays irrespective of the ordering of elements.

The above code will only work if both arrays have non-duplicate items.

Furness answered 26/2, 2020 at 6:12 Comment(5)
Note that this solution has an O(n²) runtime, while this problem can be solved with an O(n) runtime using additional space.Maccabean
I think this will give a false positive if say array1 has duplicate entries. In arrays, there is no guarantee of non duplication. In your above example, if array 1 was say [1,1,5], it would return true.Chittagong
for array of objects how can check it?Orthodontist
@Maccabean - can you elaborate "using additional space"? Which of these solutions has the O(n) runtime as indicated?Knotweed
@GiffordN. https://mcmap.net/q/134552/-how-to-know-if-two-arrays-have-the-same-values is an O(n) solutionMaccabean
V
14

Object equality check:JSON.stringify(array1.sort()) === JSON.stringify(array2.sort())

The above test also works with arrays of objects in which case use a sort function as documented in http://www.w3schools.com/jsref/jsref_sort.asp

Might suffice for small arrays with flat JSON schemas.

Vesica answered 13/2, 2014 at 18:1 Comment(0)
C
11

For 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)
Cent answered 11/2, 2022 at 13:30 Comment(3)
Best straight answer here.Immediacy
What does difference? mean in your ternary operator in the console.log?Gomar
@dilungasr that's a maybe operator. If difference were null, it wouldn't throw. Not really useful in this example... but habit for some. Also, this answer only works 1 way, and only if you're adding values to it. It could work for some use cases, but doesn't answer the question, unfortunately.Gawlas
L
3

When you compare those two arrays, you're comparing the objects that represent the arrays, not the contents.

You'll have to use a function to compare the two. You could write your own that simply loops though one and compares it to the other after you check that the lengths are the same.

Lafountain answered 3/6, 2011 at 15:37 Comment(0)
C
3

I had simple integer values in a Game project
Had less number of values in each array, also, needed that original array untouched
So, I did the below, it worked fine. (Code edited to paste here)

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;

Hope that helps.

Contiguous answered 8/7, 2015 at 12:8 Comment(0)
T
3

Using ES6

We'll use Ramda's equals function, but instead we can use Lodash's or Underscore's isEqual:

const R = require('ramda');

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

Using the spread opporator, we avoid mutating the original arrays, and we keep our function pure.

Teteak answered 1/8, 2018 at 15:32 Comment(1)
I don't see how this is at all based on ES6. The key thing is cloning the array before sorting which can be done with arr1.slice().sort(). It's Ramda using all the work in the end.Laughable
O
3

You can use reduce instead of loops to appear clever, but at the risk of having your fellow developers think of you as a smart-ass.

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;
  }
}
Octoroon answered 23/4, 2020 at 5:16 Comment(0)
H
3

Most of the other solutions use sort, O(n*log n), use libraries or have O(n^2) complexity.

Here is a pure Javascript solution with linear complexity, O(n):

/**
 * 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
}

Tests:

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
Hejaz answered 9/8, 2020 at 21:55 Comment(6)
Hey, that’s an awesome entry! It’s quite convoluted but it does make sense. I have a question: I’m not very familiar with Big O notation, but surely this algorithm is O(2n)? Don’t think that makes very much of a difference though.Geometrid
@CarlosPrecioso That's correct and O(2n) = O(n). The complexity doesn't change multiplying by a constant factorHejaz
This doesn't handle cases like compareArrays(['1'], [1]) or compareArrays([2, 2], [1, 2])Brede
@SC1000 My examples only have arrays of strings or numbers.Brede
@SC1000 Indeed. In each example the arrays have different values, yet the function returns true. The expected result for comparing ['1'] against [1] would be false, as the arrays have different values. Also [2, 2] and [1, 2] are arrays with different values so the expected result is false. Also, if you do compareArrays([1, 2], [2, 2]) it returns false, so your function isn't commutative; Which, I feel, is unexpected in a function like this.Brede
@ChrisKent The updated function handles all cases. Now it also has an optional parameter to enforce the order, if needed. Thank you for your feedback.Hejaz
S
3

You didn't seem to care about perf, not sure any of the other answer did either.

Here's some benchmarks for both sameArrayMembers (ie, [1,2,2] != [1,1,2]) as well as sameArrayMembersAsSet (ie, [1,2,2] == [1,1,2])

Didn't check for [1,1,2] same as [1,2] which I probably should given if you're claiming to check for sets than you shouldn't have the length check.

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/[email protected]/lodash.js"></script>
<script src="https://unpkg.com/[email protected]/benchmark.js"></script>

The results will probably change over time since JS engines get updated. Here's some results from 2020/09/28

Chrome 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

Firefox 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
Scrod answered 27/9, 2020 at 11:20 Comment(0)
B
3

Another one line solution:

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

or

[...array1, ...array2].filter((item, index, currentArr) => currentArr.lastIndexOf(item) == currentArr.indexOf(item)).length == 0;
Barabarabarabas answered 21/10, 2020 at 10:52 Comment(0)
I
3
  1. Check if two arrays have the same values but may not be in the same order

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. Check if two arrays have the same value and the same order (just don't sort it.)

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
Internalcombustion answered 18/6, 2021 at 6:25 Comment(1)
this one does the job for my use case, I need to check if there are same, and same only values in both arrays, regardless the order. Its clean and short piece of codeAvelin
A
3

The most easiest way to get the result is below

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

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

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

console.log(result)
Azure answered 6/5, 2022 at 8:7 Comment(0)
A
2

Answering after long time but hope this will help somebody who looking for a simple solution and modern newbies.

Now we can achieve this using multiple libraries like lodash, underscore, etc. (These becomes part of the project nowadays due to simplicity, multiple features and high usage)

You can use intersection from lodash library.

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

This will work for any data type..

Aalst answered 5/9, 2019 at 15:24 Comment(0)
B
2

Try this

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;
}
Bellamy answered 28/6, 2020 at 10:27 Comment(0)
V
2

Code & Explanation

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));

Disclaimer

This only supports simple types like your strings, numbers, booleans, etc. It won't really look far into your objects or arrays unless you edit the code to make it recursive, however that doesn't really seem like an issue in terms of answering the question itself. You provided numbers, so my answer will work with numbers.

Vinasse answered 22/8, 2021 at 8:37 Comment(0)
S
1

Simple solution for shallow equality using ES6:

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

Creates shallow copies of each array and sorts them. Then uses some() to loop through arr1test values, checking each value against the value in arr2test with the same index. If all values are equal, some() returns false, and in turn equal evaluates to true.

Could also use every(), but it would have to cycle through every element in the array to satisfy a true result, whereas some() will bail as soon as it finds a value that is not equal:

const equal = arr1test.every((val, idx) => val === arr2test[idx])
Stroy answered 12/5, 2020 at 11:53 Comment(2)
Just like some() stops execution as soon as something matches, every() stops execution as soon as something does not match, so there is no performance difference between the two. Also, you are not checking if arr2 contains something that arr1 did not, so this code does not work as expected.Glassman
@Glassman good note about the performance (non)issue, thanks. I think your reservation about arr2 containing something not in arr1 could be handled by first checking that the array lengths are the same, could it not?Cushitic
P
0

If you are using the Prototype Framework, you can use the intersect method of an array to find out of they are the same (regardless of the order):

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

if(array1.intersect(array2).length === array1.length) {
    alert("arrays are the same!");
}
Persas answered 25/1, 2013 at 9:27 Comment(3)
This doesn't work - [1,2].intersect([1,2,3]).length === [1,2].length returns true. You should compare the length of the original arrays too, I've edited the post to demonstrate.Precede
Actually I've just realised my suggested edit doesn't work in the case of duplicates... e.g. it will return false for array1 = [1,1,2]; array2 = [1,1,2];... the original answer doesn't fail for that input.Precede
You can do the opposite with _.difference(array1, array2).length;Keslie
A
0

kindly check this answer

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;
    }
}
}
Agouti answered 8/8, 2017 at 7:36 Comment(3)
This is functionally equivalent to this answer, save for a couple of errors. First, this should all be wrapped within a function, or the return will have no effect. Second, you should check the sorted arrays, as [1,2] and [2,1] will be detected as not the same. Third and most important, this will actually only check if some element is the same. The conditional should be if (array1!==array2) {return false;}. Maybe this can help you in the future!Geometrid
And as an extra comment, do try to use indentation for better understanding of the code flow, as well as clearer variable names. E.g.: array1 and array2 could be renamed elem1 and elem2. Both these tips will save you plenty of headaches in the future!Geometrid
On further inspection, why the double loop? Both arrays should be the same length, and if not, they are directly not equal. This way you can use only one loop. Right now, this code checks if any of the elements of the first array are anywhere in the second one. Check this answer to see how you should implement it. Good luck in your JavaScript journey!Geometrid
C
0

I have another way based on the accepted answer.

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;
}
Cadastre answered 3/7, 2020 at 20:14 Comment(2)
Hey, welcome to StackOverflow! While this answer would work in some cases, there'd be some specific cases where it wouldn't. First off, be mindful that the .sort() modifies the original array. Nowadays that's considered poor hygiene, that's why the original answer does a .concat() first, to make a copy.Geometrid
And second point, this would not work consistently with the rest of JavaScript. {foo:"bar"} === {foo:"bar"} returns false (they are two distinct objects created separately); so compareArrays([{foo:"bar"}], [{foo:"bar"}]), should also return false for consistency. However, with your implementation, it returns true, as the string representation of the objects is the same. That could be a desired behaviour, or not, but one to be mindful of in any case.Geometrid
C
0

A function to Compare two Arrays, to check if both has same elements. Even if they are out of order...

It's good for simple arrays. [String,Number,Boolean,null,NaN].

I don't use .sort(), it modifies the original array. Some say's its bad...

Caution. This function is limited it can't compare Objects"[],{}" or functions within these Arrays, arrays it's self are Objects.

   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);
    }

Clavius answered 26/7, 2020 at 19:38 Comment(0)
A
0

If you only want to test for primitive values, you can try:

if(JSON.stringify(arr1.sort()) !== JSON.stringify(arr2.sort())) {
  console.log('invalid');
}
Alcott answered 20/10, 2020 at 8:8 Comment(0)
S
0

This worked fine for me, but I don't understand why some people use the concat method on the arrays.

/**
 * 
 * @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);

Output

false
Bad params!

Bad params!

true
true
true
true
false
true
true
true
true
Spermophile answered 29/11, 2021 at 18:32 Comment(0)
S
0

If the order of the array elements are not important, you could try

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
Stambul answered 23/1, 2022 at 10:52 Comment(0)
C
0

Interpretation

The question is slightly ambiguous, but I will interpret it as follows:

How can I write a function that detects if a one-depth array B is a shuffled version of array A?

Therefore:

  1. Using includes() will not work because we need to not only check that A "includes" all of B's values and vice versa, but we need to ensure that the number of occurrences of each item is the same between the arrays as well. For example, using includes() logic on these array will result in a false positive:
A: [true, false, true]
B: [true, true, false]

A and B are the same length and A includes all of B's items and vice versa. But clearly B is not a reshuffling of A.

  1. We cannot use the native Javascript implementation of Set because a Set will remove repeats of values.

Pseudocode

assert typeof A1 and A2 === Array
assert A1 length = A2 length

for each element E of A1:
  delete E from A2
  
return true if A2 is empty

Explanation

Let A and B be two lists.

Case 1

A and B are different lengths. Return false since the longer list must have elements not present in the shorter list.

Case 2

A and B are the same length, and B is a reshuffling of A. For each element e in A, subtract its count in B by exactly the number of its occurrences in A. B is empty, return true.

Case 3

A and B are same lengths, but the count of element x in B is less than the count of element x in A. Since A and B are the same lengths, there is also some element y whose count in A is less than y's count in B. For each element e in A, subtract its count in B by exactly the number of its occurrences in A. Since there is some element y whose count in A is less than y's count in B, B will always have at least one value with a remaining count. Return false.

Implementation Details

My implementation depends on the MultiSet data structure from the Mnemonist package . This is a special type of Set that allows you to have duplicate values. We could also accomplish the same task using only arrays, but deleting from an array is less efficient than deleting from a Set.

Implementation Code

const MultiSet = require('mnemonist/multi-set');

export const arraysHaveSameValues = <T> (a1: Array<T>, a2: Array<T>): boolean => {
  if (!Array.isArray(a1) || !Array.isArray(a2)) return undefined;
  else if (a1.length !== a2.length) return false;
  else {
    const s2 = MultiSet.from(a2);
    const deleteFromS2 = (x) => s2.remove(x);
    a1.forEach(deleteFromS2);
    return s2.size === 0;
  }
};
Chlorinate answered 20/6, 2023 at 21:49 Comment(0)
K
0

Using length works.

This method returns false immediately if the arrays are different lengths. Next it filters both arrays for matches. The Set is extra overhead but it's simple and works because it can't contain duplicates. If the length is more than 1 something didn't match.

function checkIfArraysContainSameValues(arrayOne, arrayTwo) {

    const arrayOneLength = arrayOne.length;
    const arrayTwoLength = arrayTwo.length;

    if (arrayOneLength != arrayTwoLength) return false;     

    const arrayOneMatchesLength = arrayOne.filter( element => arrayTwo.includes(element)).length;
    const arrayTwoMatchesLength = arrayTwo.filter( element => arrayOne.includes(element)).length;
            
    return new Set([arrayOneLength, arrayTwoLength, arrayOneMatchesLength, arrayTwoMatchesLength ]).size === 1 ? true : false;

}
Kush answered 16/12, 2023 at 22:7 Comment(0)
E
-1

If you want to compare two arrays and check if any object is same in both arrays it will works. Example :

Array1 = [a,b,c,d]
Array2 = [d,e,f,g]

Here, 'd' is common in both array so this function will return true value.

  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;
  }
Evania answered 25/1, 2020 at 11:50 Comment(0)
L
-2

Here is my solution without sorting:

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
Lilith answered 9/6, 2021 at 13:5 Comment(1)
this doesn't work for example if a1 = ['a','a','b'] and a2 = ['a', 'b', 'c']Theatricalize

© 2022 - 2024 — McMap. All rights reserved.