1

I am trying to filter an array in order to check if a specific value of all nested objects (I have items containing other items) matches my condition.

The following is working just fine, but I need to iterate the process until all matching elements are found.

// My filter
var itemsNumber = e.items.filter(function(superhero) {
    return superhero.group && superhero.group.items && superhero.group.items[0] && superhero.group.items[0].id === "1517" 


    /* I basically need to iterate the following process:

            || superhero.group && superhero.group.items && superhero.group.items[1] && superhero.group.items[1].id === "1517"

            || superhero.group && superhero.group.items && superhero.group.items[2] && superhero.group.items[2].id === "1517"

            || superhero.group && superhero.group.items && superhero.group.items[3] && superhero.group.items[3].id === "1517"

            || superhero.group && superhero.group.items && superhero.group.items[4] && superhero.group.items[4].id === "1517"

        ... And so on.

    */

});

 console.log(itemsNumber.length);

Thanks in advance.

1 Answer 1

3

You're looking for the some method:

return superhero.group &&
       superhero.group.items &&
       superhero.group.items.some(({id}) => id === "1517");

or if you need that in ES5:

return superhero.group &&
       superhero.group.items &&
       superhero.group.items.some(function(item) {
        return item.id === "1517";
       });

some calls its callback once for each entry in the array and either returns true the first time the callback returns a truthy¹ value, or returns false if the callback never returns a truthy value (including if there were no entries in the array at all). That is, it checks if "some" (really, "any') item in the array matches the predicate expressed by the callback.

Here's an example (in ES2015+) for both when the condition is true and when it's false:

function check(superhero) {
    return superhero.group &&
           superhero.group.items &&
           superhero.group.items.some(({id}) => id === "1517");
}

function test(superhero, expect) {
    const result = check(superhero);
    console.log(`Checking ${JSON.stringify(superhero)}: ${result} <= ${!result === !expect ? "OK" : "ERROR"}`);
}

test({group: {items: [{id: "1"}, {id: "1517"}, {id: "9999"}]}}, true);
test({group: {items: [{id: "1"}, {id: "2"}, {id: "3"}]}}, false);


¹ "truthy value" - a "truthy" value is any value that isn't "falsy." A falsy value is a value that evaluates to false when used as a condition (such as if (x)). The falsy values are 0, "", null, undefined, NaN, and of course, false.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for your explanation! I just tried your code, unfortunately it seems to miss some items while counting theirs length. I guess I need to chek "every" items contained in "every" group.
@Antony - I'm not sure what you mean by "every group." There's only one group shown in your code (which has a property called items, which is an array).
@Antony This answer is sound based on what you provided, could some group item id values in your data be actual integers not strings? i.e. does using loose equality ( id == "1517") catch those missed items?
On second look at the commented example, we may have overlooked the or op (||) in which case try using .some instead of .every.
@David .some actually did the trick. Thanks you all for your help!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.