首页 > 解决方案 > javascript - better search value script in nested arrays

问题描述

I need to search for a value in nested array to answer the question :

Is there an emailAddress of "type":"CONTACT" with "value":"email4@example.com"?

I wrote the following basic algorithm (see fiddle) which is giving the expected result, but I guess there is a better and shorter way to solve it ...

const infos = [
    {
        "resourceName":"name1",
        "id":"id1",
        "emailAddresses":[
            { "metadata":{ "primary":true,  "source":{ "type":"CONTACT", "id":"m1" } , "value":"email1@example.com"}},
            { "metadata":{ "primary":false, "source":{ "type":"CONTACT", "id":"m2" } , "value":"email2@example.com"}}
        ]
    },
    {
        "resourceName":"name2",
        "id":"id2",
        "emailAddresses":[
            { "metadata":{ "primary":true,  "source":{ "type":"FAMILY", "id":"m3" } , "value":"email3@example.com"}},
            { "metadata":{ "primary":false, "source":{ "type":"CONTACT", "id":"m4" } , "value":"email4@example.com"}},
            { "metadata":{ "primary":false, "source":{ "type":"BUSINESS", "id":"m5" } , "value":"email5@example.com"}}
        ]
    },
    {
        "resourceName":"name3",
        "id":"id3",
        "emailAddresses":[
            { "metadata":{ "primary":true,  "source":{ "type":"CONTACT", "id":"m5" } , "value":"email6@example.com"}},
            { "metadata":{ "primary":false, "source":{ "type":"FAMILY", "id":"m6" } , "value":"email7@example.com"}}
        ]
    }
];

const search_email = "email4@example.com";
let parent_key = null;

infos.forEach( info => {
    info.emailAddresses.forEach( ema => {
        if ((ema.metadata.source.type === 'CONTACT') && (ema.metadata.value === search_email )) {
            parent_key = info.id;
        }
    })
});

if ( parent_key === null) {
    console.log('NOT FOUND');
} else {
    console.log('FOUND - PARENT KEY: ', parent_key);
}

I can stop the search on the first found state... just need to know if the searched email does exist.

标签: javascriptecmascript-6

解决方案


You can use array#some to iterate through infos array, then again use array#some to look inside emailAddresses array where source type is CONTACT and value is the email address you provided.

The some() method tests whether at least one element in the array passes the test implemented by the provided function.

If an element is found, array#some() immediately returns true.

const infos =[ { "resourceName":"name1", "id":"id1", "emailAddresses":[ { "metadata":{ "primary":true, "source":{ "type":"CONTACT", "id":"m1" } , "value":"email1@example.com"}}, { "metadata":{ "primary":false, "source":{ "type":"CONTACT", "id":"m2" }, "value":"email2@example.com"}} ] }, { "resourceName":"name2", "id":"id2", "emailAddresses":[ { "metadata":{ "primary":true, "source":{ "type":"FAMILY", "id":"m3" } , "value":"email3@example.com"}}, { "metadata":{ "primary":false, "source":{ "type":"CONTACT","id":"m4" } , "value":"email4@example.com"}}, { "metadata":{ "primary":false, "source":{ "type":"BUSINESS", "id":"m5" } , "value":"email5@example.com"}} ] }, { "resourceName":"name3", "id":"id3", "emailAddresses":[ { "metadata":{ "primary":true, "source":{"type":"CONTACT", "id":"m5" } , "value":"email6@example.com"}}, { "metadata":{ "primary":false, "source":{ "type":"FAMILY", "id":"m6" } , "value":"email7@example.com"}} ] } ],
    searchEmail = "email4@example.com";
    found = infos.some(({emailAddresses}) =>
              emailAddresses.some(({metadata}) => metadata.source.type === 'CONTACT' && metadata.value === searchEmail)
            );
console.log(found);


推荐阅读