Об'єднайте масиви в один масив після фільтрації


14

У мене є масив об'єктів, де я беру лише масив локацій. Моя мета - об'єднати ці масиви локацій в один масив, однак я не зможу це зробити і отримати порожній масив. Ось як я це роблю:

let results = [{
    id: '1',
    locations: ['aaaa', 'bbbbbb', 'cccccc']
  },
  {
    id: '2',
    locations: []
  },
  {
    id: '3',
    locations: ['ddd', 'aaadsad', 'sefd']
  },
  {
    id: '4',
    locations: ['ffff', 'eeee', 'sfdsfsd']
  },
];
const locationIds = [].concat.apply([], ...results.filter(s => s.locations && s.locations.length > 0).map(({
  locations
}) => ({
  locations
})));

console.log(locationIds);

що я тут роблю неправильно? Результат повинен бути ['aaaa', 'bbbbbb', 'cccccc', 'ddd', 'aaadsad', 'sefd', 'ffff', 'eeee', 'sfdsfsd'];

Відповіді:


9

Вам тут не потрібно filter. Просто скористайтеся mapметодом, передавши надану функцію зворотного виклику, яка застосовується до кожного елемента масиву.

let results = [{ id: '1', locations: ['aaaa', 'bbbbbb', 'cccccc'] }, { id: '2', locations: [] }, { id: '3', locations: ['ddd', 'aaadsad', 'sefd'] }, { id: '4', locations: ['ffff', 'eeee', 'sfdsfsd'] }, ];

const locationIds = [].concat(...results.map(s => s.locations));

console.log(locationIds);


1
@ user122222, ласкаво просимо! Ви можете створити власну реалізацію на flatMapзразок тут: stackoverflow.com/questions/39837678/…
Mihai Alexandru-Ionut

7

Ви можете спробувати flatMap():

flatMap()Метод спочатку відображає кожен елемент з допомогою функції відображення, а потім згладжує результат в новий масив. Це ідентично map()за яким слід flat()з глибини 1 , але flatMap()часто буває вельми корисно, оскільки злиття обох в одному з способів є трохи більш ефективним.

let results = [{
    id: '1',
    locations: ['aaaa', 'bbbbbb', 'cccccc']
  },
  {
    id: '2',
    locations: []
  },
  {
    id: '3',
    locations: ['ddd', 'aaadsad', 'sefd']
  },
  {
    id: '4',
    locations: ['ffff', 'eeee', 'sfdsfsd']
  },
];
const locationIds = results.flatMap(i => i.locations);
console.log(locationIds);


6

Ви можете познайомитися Array#flatMapз потрібним майном. Якщо властивість не задано, додайте масив за замовчуванням || [].

let results = [{ id: '1', locations: ['aaaa', 'bbbbbb', 'cccccc'] }, { id: '2', locations: [] }, { id: '3', locations: ['ddd', 'aaadsad', 'sefd'] }, { id: '4', locations: ['ffff', 'eeee', 'sfdsfsd'] }],
    locationIds = results.flatMap(({ locations }) => locations);

console.log(locationIds);
.as-console-wrapper { max-height: 100% !important; top: 0; }


2
Добре згадати .flatMap не працює в Edge та IE без поліфілів.
Зиднар

3

Можна також вирішити за допомогою функції зменшення від Array.prototype.

var newResults = results.reduce(function(acc, curr) {
    return acc.concat(curr.locations)
  },[]
)

сподіваюся, що це допомагає


2

Я занадто довго витрачав на це, щоб не розміщувати власне рішення - цікава загадка для мене, хоча інші відповіді, без сумніву, більш ефективні та читабельні. Він використовує таку саму стратегію, що і ваша оригінальна публікація, яка може допомогти вказати, де вона пішла не так.

const locationIds = [].concat
                    .apply([], results.filter(result => 
                    result.locations && result.locations.length > 0)
                    .map(result => { return result.locations }));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.