Alaa Khalila
Alaa Khalila

Reputation: 169

How to check if an array contains another object's values?

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

Answers (5)

T.J. Crowder
T.J. Crowder

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

Tigran Abrahamyan
Tigran Abrahamyan

Reputation: 776

const compare = (array, object) => Object.values(object).every(n => array.includes(n));

Upvotes: 1

Nina Scholz
Nina Scholz

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

Greedo
Greedo

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

user835611
user835611

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

Related Questions