javaScript filter nested objects and arrays

15,098

Solution 1

You can use filter and some

Here nested some is used to check whether any of dish_has_categories has CategoryId equal to '8', if it is true then we include that menu in final output else we don't

const data =[{ menuName: "Hot dogs", menu: [ { dishId: '1', dish_has_categories: [{ CategoryId: '8' }] }, { dishId: '2', dish_has_categories: [{ CategoryId: '9' }] }] }, { menuName: "Burgers", menu: [{ dishId: '3', dish_has_categories: [{ CategoryId: '6' }] }, { dishId: '4', dish_has_categories: [{ CategoryId: '4' }] }] }, { name: "Drinks", menu: [] } ]

let op = data.filter(val => {
  let menu = val.menu.some(({dish_has_categories}) => dish_has_categories.some(({CategoryId}) => CategoryId === '8'))
  return menu
})

console.log('filtered values -->\n',op)

let names = op.map(({menuName})=> menuName)

console.log('Names --> \n', names)

Solution 2

You can use filter() with nested some().

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

const data = [{ menuName: "Hot dogs", menu: [ { dishId: '1', dish_has_categories: [{ CategoryId: '8' }] }, { dishId: '2', dish_has_categories: [{ CategoryId: '9' }] }] }, { menuName: "Burgers", menu: [{ dishId: '3', dish_has_categories: [{ CategoryId: '6' }] }, { dishId: '4', dish_has_categories: [{ CategoryId: '4' }] }] }, { name: "Drinks", menu: [] } ]

const res = data.filter(x => 
                x.menu.some(y => 
                    y.dish_has_categories.some(z => z.CategoryId === '8')
                )
            );
console.log(res)
Share:
15,098

Related videos on Youtube

margherita pizza
Author by

margherita pizza

Hello World, I'm Pathum kalhan. Senior full stack JavaScript developer based on Sri lanka.

Updated on September 15, 2022

Comments

  • margherita pizza
    margherita pizza over 1 year

    My use case is something like this.

    1. I have an array that has an object.
    2. That each object has an array called menu
    3. Again that menu array has objected.
    4. That each object has an array dish_has_categories
    5. In dish_has_categories array, if there is an object with CategoryId is equal to 8 I want to filter out that root object.

    My original data object

    const data = [{
            menuName: "Hot dogs",
            menu: [
                {
                dishId: '1',
                dish_has_categories: [{
                    CategoryId: '8'
                }]
            },
             {
                dishId: '2',
                dish_has_categories: [{
                    CategoryId: '9'
                }]
            }]
        },
        {
            menuName: "Burgers",
            menu: [{
                dishId: '3',
                dish_has_categories: [{
                    CategoryId: '6'
                }]
            }, {
                dishId: '4',
                dish_has_categories: [{
                    CategoryId: '4'
                }]
            }]
        },
        {
            name: "Drinks",
            menu: []
        }
    ]

    My expect result is

    [{
            menuName: "Hot dogs",
            menu: [
                {
                dishId: '1',
                dish_has_categories: [{
                    CategoryId: '8'
                }]
            },
             {
                dishId: '2',
                dish_has_categories: [{
                    CategoryId: '9'
                }]
            }]
        }]
        

    what I've done up to now is

    const data2 = data.filter(element => {
        return element.menu.length > 0
    })
    

    I have no idea how to deep filter inside nested objects and arrays. Hope my question is clear to you all.

  • margherita pizza
    margherita pizza almost 5 years
    Thanks a lot. This works! If I want to push this menu name ("Hot dogs") to new separate array. Where do I can do that?
  • Syed mohamed aladeen
    Syed mohamed aladeen almost 5 years
    Hi, can you please explain, why you are using z.CategoryId === '8'? 8 is hardcoded here.
  • margherita pizza
    margherita pizza almost 5 years
    Thanks a lot. This works! If I want to push this menu name ("Hot dogs") to new separate array. Where do I can do that?
  • Code Maniac
    Code Maniac almost 5 years
    @PathumSamararathna you want to get names of filtered values or all the values ? you can simply use map and return name only from map
  • Code Maniac
    Code Maniac almost 5 years
    @PathumSamararathna i have added example of getting names in new array too you can check :) always happy to help :)
  • Maheer Ali
    Maheer Ali almost 5 years
    @PathumSamararathna You can use map() for that I have updated.
  • Maheer Ali
    Maheer Ali almost 5 years
    @SyedMohamedAladeen Becasue OP asked )"In dish_has_categories array, if there is an object with CategoryId is equal to 8 I want to filter out that root object."_