I transformed the object values into a new array
I think a Set would be even better, since it has a has method with sub-linear performance and the semantics are nice and clear. But the easiest way to get to a Set is via an array, so... :-)
Once you have the Set, it's a matter of looping, in this case probably with every:
const compare = (array, object) => {
const values = new Set(Object.values(object));
return array.every(v => values.has(v));
};
every returns true if the callback always returns a truthy value, or returns false the first time the callback returns a falsy value (short-circuiting at that point, no reason to keep looking if the answer is "no").
If you want to stick with an array, though, you could use includes in the every. It has linear performance, but in 99.9999% of situations, the performance isn't critical anyway:
const compare = (array, object) => {
const values = Object.values(object);
return array.every(v => values.includes(v));
};
As Nina points out, adding a check that the lengths match would short-circuit faster. Here's what that looks like for both of the above:
Set:
const compare = (array, object) => {
const valuesArray = Object.values(object);
if (valuesArray.length !== array.length) {
return false;
}
const values = new Set(valuesArray);
return array.every(v => values.has(v));
};
Array:
const compare = (array, object) => {
const values = Object.values(object);
return array.length === values.length && array.every(v => values.includes(v));
};
You could go even further and add
if (array.length === 0) {
return true;
}
at the very beginning of both.
Object.values(object).every(val => array.indexOf(val) !== -1)compare(["one", "three", "two"], { 0: "one", 1: "two", 2: "three" });give (index of "three" here doesn't align with the key-index in the object)