Reputation: 169
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
Upvotes: 3
Views: 148
Reputation: 1074108
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.
Upvotes: 5
Reputation: 776
const compare = (array, object) => Object.values(object).every(n => array.includes(n));
Upvotes: 1
Reputation: 386550
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
Upvotes: 3
Reputation: 3549
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
Upvotes: 3
Reputation: 2366
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.
Upvotes: 3