0

What is the best way to check if two arrays have the same/equal values (in any order) in JavaScript?

These values are just a primary keys of database entities, so they always will be different

const result = [1, 3, 8, 77]
const same = [8, 3, 1, 77]
const diff = [8, 3, 5, 77]

areValuesTheSame(result, same) // true
areValuesTheSame(result, diff) // false

How should areValuesTheSame method look like?

P.S. This question looks like a duplicate but I didn't find anything relative to Javascript.

Yegor
  • 3,652
  • 4
  • 22
  • 44

3 Answers3

3

I'm making the following assumptions:

  • The arrays only contain numbers.
  • You don't care about the order of the elements; rearranging the arrays is OK.

Under those conditions we can simply convert each array to a canonical string by sorting it and joining the elements with e.g. a space. Then (multi-)set equality boils down to simple string equality.

function areValuesTheSame(a, b) {
    return a.sort().join(' ') === b.sort().join(' ');
}

const result = [1, 3, 8, 77];
const same = [8, 3, 1, 77];
const diff = [8, 3, 5, 77];

console.log(areValuesTheSame(result, same));
console.log(areValuesTheSame(result, diff));

This is probably the laziest / shortest approach.

melpomene
  • 84,125
  • 8
  • 85
  • 148
  • @MisterJojo Yes, that's what I said (assumption #2). – melpomene Jun 23 '19 at 17:27
  • your answer is so good, cause its more understandable, as someone mentioned in question, order/values place isn't matter(and it's my case), so I'll accept your solution. But @ghoul-ahmed have a nice one, too) – Yegor Jun 23 '19 at 17:36
  • You could also use `JSON.stringify` instead of join, to make it also work for string or any other primitive arrays. – georg Jun 23 '19 at 18:42
  • Pretty certain that `sort` modifies the array in place, so if you are relying on the original order of either of your arrays staying the same, this might not be the best option for you. – Alex Currie-Clark Aug 12 '22 at 22:14
2

You could count all elements with a Map (this is type save) up for the one array and down for the other and check if all items have a final count of zero.

function haveSameValues(a, b) {
    const count = d => (m, v) => m.set(v, (m.get(v) || 0) + d)
    return Array
        .from(b.reduce(count(-1), a.reduce(count(1), new Map)).values())
        .every(v => v === 0);
}

const result = [1, 3, 8, 77]
const same = [8, 3, 1, 77]
const diff = [8, 3, 5, 77]

console.log(haveSameValues(result, same)); // true
console.log(haveSameValues(result, diff)); // false
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

Try this:

const result = [1, 3, 8, 77]
const same = [8, 3, 1, 77]
const diff = [8, 3, 5, 77]
const areValuesTheSame = (a,b) => (a.length === b.length) && Object.keys(a.sort()).every(i=>a[i] === b.sort()[i])


console.log(areValuesTheSame(result, same)) // true
console.log(areValuesTheSame(result, diff)) // false
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
Ghoul Ahmed
  • 4,446
  • 1
  • 14
  • 23
  • 1
    That doesn't work at all. If you add `9` to `same` (as in `[8, 3, 1, 77, 9]`), it still thinks it's equal to `result`. – melpomene Jun 23 '19 at 16:57
  • Instead of `Object.keys()`, just use `a.sort(), b.sort().every((x, i) => x == a[i])`. Especially don't call `b.sort()` during every comparison! – Bergi Jun 23 '19 at 17:53
  • @MisterJojo If order doesn't matter, it probably doesn't matter to change it. If it matters, it's trivial to clone the arrays beforehand. – Bergi Jun 23 '19 at 17:53