Найти объект внутри массива внутри другого массива - PullRequest
0 голосов
/ 17 мая 2018
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'}
    ]
},

]

Я хочу найти объект из массива внутри другого массива

bigArray.find(b => b.children.find(c=>c.City === 'city1'))

код выше верните ARRAY отца

bigArray.forEach(b => b.children.find(c=>c.City === 'city1'))

и этот возврат не определен

Какой лучший способ вернуть нужный объект?

Ответы [ 3 ]

0 голосов
/ 17 мая 2018

Вы также можете сделать это без выравнивания массива.

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))});
0 голосов
/ 17 мая 2018

Дети могут родиться в одном и том же городе, поэтому find() не особенно подходит для этой проблемы, поскольку возвращает только первый результат, который ищет. В этом случае filter() - это функция, которая нам нужна.

Ниже мы называем filter внутри из reduce(). Это отличается от другого ответа, поскольку не повторяет ваши входные данные более одного раза. Другой ответ сначала создаст целый массив дочерних элементов, затем во второй итерации выберите те, которые соответствуют вашему запросу по городу.

Кроме того, этот ответ повторяется по каждому президенту один раз и добавляет всех подходящих потомков к результату по пути.

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

В ваших входных данных каждый ребенок имеет уникальный город, поэтому он не дает хорошей демонстрации. Я добавил еще нескольких детей, родившихся в city5, чтобы мы могли увидеть ответ, включающий нескольких детей

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' }
// ]

Другой ответ, приведенный здесь, сломался бы, если бы в ваших данных содержался президент без children. findByCity не страдает от этой проблемы

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' }
  ]

Разверните программу ниже, чтобы запустить ее в вашем браузере

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' }
// ]
0 голосов
/ 17 мая 2018

Сначала вы можете записать этот массив в массив внутренних объектов, а затем использовать filter() или 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...