简体   繁体   中英

Filter nested array of objects based on a property value

HI All I am new to JavaScript, I am having nested array of objects my aim is to filter out the object whose role array consists of value like " _admin" ' ' can be any thing. My data looks like this

[
    {
        name:'tom',
        process:'flipkart',
        master:'pharma',
        profiles: [
            {
                level:'begginer',
                language:'hindi',
                role:['flp_admin','flp_teacher']
            }
        ]
    
    
    },
    {
        name:'jeo',
        process:'amazon',
        master:'science',
        profiles: [
            {
                level:'begginer',
                language:'english',
                role:['amz_admin']
            }
        ]
    
    
    },
    {
        name:'jerry',
        process:'email',
        master:'it',
        profiles: [
            {
                level:'begginer',
                language:'urdu',
                role:['eml_teacher']
            }
        ]
    
    }
]

could any one please tell me how can I filter the objects

codepen

 const data = [ { name: "tom", process: "flipkart", master: "pharma", profiles: [ { level: "begginer", language: "hindi", role: ["flp_admin", "flp_teacher"] } ] }, { name: "jeo", process: "amazon", master: "science", profiles: [ { level: "begginer", language: "english", role: ["amz_admin"] } ] }, { name: "jerry", process: "email", master: "it", profiles: [ { level: "begginer", language: "urdu", role: ["eml_teacher"] } ] } ]; const filterData = data.filter(({ profiles }) => { return profiles.filter(({ role }) => { return role.some(str => str.includes('_admin')) }).length }) console.log(filterData)

If you don't want to use any library (like lodash) this could be one approach:

myArray.filter(item => item.profiles.some(p => /_admin/i.test(p.role)))

It will return an array with objects for names 'tom' and 'jeo'.

  • item.profiles.some(p => /_admin/i.test(p.role)) indicates if there is any profile containing '_admin' for one object (item).

  • myArray.filter will return all objects (items) that match with previous .some condition to true.

Here is a one-liner for you,

data.filter(item => item.profiles.some((profile)=> profile.role.some((roleItem) => roleItem.includes('_admin'))))

Here data is your array.

Let me just break it up for you,

data.filter((item) => {
    const itemHasRoleAdmin = item.profiles.some((profile) => {
       const profileHasRoleAdmin = profile.role.some((roleItem) => {
           if(roleItem.includes('_admin')) return true;
           else return false;
       });

       if(profileHasRoleAdmin) return true;
       else return false
    });

    if(itemHasRoleAdmin) return true;
    else return false;
});

For more reading on Array.prototype.some method and Array.prototype.filter method .

Here is another solution using object-scan . It's powerful once you wrap your head around how to use it. I'm a big fan of using libraries when they make the code more readable and easier to maintain (eg for changed requirements)

 // const objectScan = require('object-scan'); const filter = (data) => objectScan(['[*].profiles[*].role'], { filterFn: ({ parents, value, context }) => { if (value.some((role) => role.endsWith('_admin'))) { context.push(parents[parents.length - 2]); return true; } return false; } })(data, []); const data = [{ name: 'tom', process: 'flipkart', master: 'pharma', profiles: [{ level: 'begginer', language: 'hindi', role: ['flp_admin', 'flp_teacher'] }] }, { name: 'jeo', process: 'amazon', master: 'science', profiles: [{ level: 'begginer', language: 'english', role: ['amz_admin'] }] }, { name: 'jerry', process: 'email', master: 'it', profiles: [{ level: 'begginer', language: 'urdu', role: ['eml_teacher'] }] }]; console.log(filter(data)); // => [ { name: 'jeo', process: 'amazon', master: 'science', profiles: [ { level: 'begginer', language: 'english', role: [ 'amz_admin' ] } ] }, { name: 'tom', process: 'flipkart', master: 'pharma', profiles: [ { level: 'begginer', language: 'hindi', role: [ 'flp_admin', 'flp_teacher' ] } ] } ]
 .as-console-wrapper {max-height: 100% !important; top: 0}
 <script src="https://bundle.run/object-scan@13.8.0"></script>

Disclaimer : I'm the author of object-scan

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM