I'm trying to make a function that returns true if all the array values are present in an object values.
I have transformed the object values into a new array called newArray; but my question is how can I compare between the given array and the new array?
const compare = function (array, object) {
const newArray =Object.values(object)
//compare here and return true/false
};
compare(["one", "two", "three"], { 0: "one", 1: "two", 2: "three" }); // => true
compare(["one", "two", "four"], { 0: "one", 1: "two", 2: "three" }); // => false
5 Answers 5
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.
Comments
You can sort both arrays and then check that they have the same length and loop through both at the same time comparing the two elements.
Comments
You can use Array.prototype.reduce():
const compare = (array, object) => {
return Object.values(object).reduce((res, cur) => {
return res && array.includes(cur);
}, 1);
};
console.log(compare(["one", "two", "three"], { 0: "one", 1: "two", 2: "three" })); // => true
console.log(compare(["one", "two", "four"], { 0: "one", 1: "two", 2: "three" })); // => false
1 Comment
every which calls out exactly what's being done.I suggest to check the length of the array and values as well.
const
compare = (array, object) => {
const values = Object.values(object)
return array.length === values.length && values.every(v => array.includes(v));
};
console.log(compare(["one", "two", "three"], { 0: "one", 1: "two", 2: "three" })); // true
console.log(compare(["one", "two", "four"], { 0: "one", 1: "two", 2: "three" })); // false
Comments
const compare = (array, object) => Object.values(object).every(n => array.includes(n));
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)