Skip to content Skip to sidebar Skip to footer

Find Object Inside Array Inside Another Array

let bigArray = [ { Name: 'Trump', children: [ {Name: 'TrumpChild1', City: 'city1'}, {Name: 'TrumpChild2', City: 'city2'} ] }, { N

Solution 1:

You can first flaten this array to an array of inner objects and then use filter() or find().

let bigArray = [
  {
      Name: 'Trump',
      children: [
                   {Name: 'TrumpChild1', City: 'city1'}, 
                   {Name: 'TrumpChild2', City: 'city2'}
      ]
  },
  {
      Name: 'Barack Obama',
      children: [
                   {Name: 'Barack Obama Child1', City: 'city3'}, 
                   {Name: 'Barack Obama Child2', City: 'city4'}
      ]
  },
  {
      Name: 'Clinton',
      children: [
                   {Name: 'Clinton Child 1', City: 'city5'}, 
                   {Name: 'Clinton Child2', City: 'city6'}
      ]
  }
];

let all = bigArray.reduce((prev, next) => prev.concat(next.children), []);
let result = all.find(obj => obj.City === 'city1');
console.log(result);

// if there can be multiple matches then use filter
let results = all.filter(obj => obj.City === 'city1');
console.log(results);

Solution 2:

Children could be born in the same city and so find() is not particularly well-suited for this problem as it only returns the first result its looking for. In this case filter() is the function we need.

Below, we call filter inside of reduce(). This is different from the other answer as it does not iterate thru your input data more than once. The other answer will first create an entire array of children, then in a second iteration, select the ones that match your city query.

Alternatively, this answer iterates thru each president once and adds any matching children to the result along the way.

const findByCity = (city, data = {}) =>
  data .reduce
    ( (result, { children = [] }) =>
        result .concat (children .filter (c => c.city === city))
    , []
    )

In your input data, each child has a unique city, so it doesn't yield a good demonstration. I've added some more children born in city5 so we can see an answer that includes multiple children

const data =
  [ { name: 'Trump'
    , children:
        [ { name: 'Trump Child 1', city: 'city1' }
        , { name: 'Trump Child 2', city: 'city2' }
        ]
    }
  , { name: 'Barack Obama'
    , children:
        [ { name: 'Barack Obama Child 1', city: 'city3' }
        , { name: 'Barack Obama Child 2', city: 'city4' }
        ]
    }
  , { name: 'Clinton'
    , children:
        [ { name: 'Clinton Child 1', city: 'city5' }
        , { name: 'Clinton Child 2', city: 'city6' }
        ]
    }
  , { name: 'Bush'
    , children:
        [ { name: 'Bush Child 1', city: 'city5' }
        , { name: 'Bush Child 2', city: 'city5' }
        ]
    }
  ]

console .log (findByCity ('city1', data))
// [ { name: 'Trump Child 1', city: 'city1' } ]

console .log (findByCity ('city5', data))
// [ { name: 'Clinton Child 1', city: 'city5' }
// , { name: 'Bush Child 1', city: 'city5' }
// , { name: 'Bush Child 2', city: 'city5' }
// ]

Another answer provided here would break if your data contained a children-less president. findByCity does not suffer from this problem

const data =
  [ // ...
  , { name: 'Bush'
    , children:
        [ { name: 'Bush Child 1', city: 'city5' }
        , { name: 'Bush Child 2', city: 'city5' }
        ]
    }

  // watch out for child-less presidents!
  , { name: 'Polk' }
  ]

Expand the program below to run it in your browser

const findByCity = (city, data = {}) =>
  data .reduce
    ( (result, { children = [] }) =>
        result .concat (children .filter (c => c.city === city))
    , []
    )

const data =
  [ { name: 'Trump'
    , children:
        [ { name: 'Trump Child 1', city: 'city1' }
        , { name: 'Trump Child 2', city: 'city2' }
        ]
    }
  , { name: 'Barack Obama'
    , children:
        [ { name: 'Barack Obama Child 1', city: 'city3' }
        , { name: 'Barack Obama Child 2', city: 'city4' }
        ]
    }
  , { name: 'Clinton'
    , children:
        [ { name: 'Clinton Child 1', city: 'city5' }
        , { name: 'Clinton Child 2', city: 'city6' }
        ]
    }
  , { name: 'Bush'
    , children:
        [ { name: 'Bush Child 1', city: 'city5' }
        , { name: 'Bush Child 2', city: 'city5' }
        ]
    }
  , { name: 'Polk' }
  ]

console .log (findByCity ('city1', data))
// [ { name: 'Trump Child 1', city: 'city1' } ]
    
console .log (findByCity ('city5', data))
// [ { name: 'Clinton Child 1', city: 'city5' }
// , { name: 'Bush Child 1', city: 'city5' }
// , { name: 'Bush Child 2', city: 'city5' }
// ]

Solution 3:

You can also do it without flattening the array.

let matches = [];

// using array.forEach(), plus && in .map() to shorten the comparison syntax
bigArray.forEach(obj => {obj.children.map(c => c.City == 'city1' &&  matches.push(c))});

// and this version works even if there is not a `children` property
bigArray.forEach(obj => {obj.children && obj.children.map(c => c.City == 'city1' &&  matches.push(c))});

Solution 4:

I had almost the same issue as here but for me i was looking for the overall Name of the element in this case the name of the father (for example name: 'Trump') i just used a double find to make it as easy and efficient as possible ^^ My code :

let bigArray = [
  {
      Name: 'Trump',
      children: [
                   {Name: 'TrumpChild1', City: 'city1'}, 
                   {Name: 'TrumpChild2', City: 'city2'}
      ]
  },
  {
      Name: 'Barack Obama',
      children: [
                   {Name: 'Barack Obama Child1', City: 'city3'}, 
                   {Name: 'Barack Obama Child2', City: 'city4'}
      ]
  },
  {
      Name: 'Clinton',
      children: [
                   {Name: 'Clinton Child 1', City: 'city5'}, 
                   {Name: 'Clinton Child2', City: 'city6'}
      ]
  }
];

const element = bigArray.find((el) => el.children.find((item) => item.City === 'city2'))
const {Name: fatherName} = element
// for the element
console.log(element)
// for the father name 
console.log(fatherName)

if you just need the name you can remove element and change it with {Name: fatherName}


Post a Comment for "Find Object Inside Array Inside Another Array"