Fusionner des tableaux en un seul tableau après filtrage

14

J'ai un tableau d'objets, où je ne prends que le tableau d'emplacements. Mon objectif est de fusionner ces tableaux d'emplacements en un seul tableau, mais je ne le fais pas et j'obtiens un tableau vide. Voici comment je le fais:

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);

ce que je fais mal ici? Le résultat devrait être ['aaaa', 'bbbbbb', 'cccccc', 'ddd', 'aaadsad', 'sefd', 'ffff', 'eeee', 'sfdsfsd'];

user122222
la source

Réponses:

9

Vous n'avez pas besoin filterici. Utilisez simplement la mapméthode en passant une fonction de rappel fournie qui est appliquée à chaque élément du tableau.

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);

Mihai Alexandru-Ionut
la source
1
@ user122222, vous êtes les bienvenus! Vous pouvez créer votre propre implémentation de flatMapcomme ici: stackoverflow.com/questions/39837678/…
Mihai Alexandru-Ionut
7

Vous pouvez essayer avec flatMap():

La flatMap()méthode mappe d'abord chaque élément à l'aide d'une fonction de mappage, puis aplatit le résultat dans un nouveau tableau. Il est identique à un map()suivi d'un a flat()de profondeur 1 , mais flatMap()est souvent très utile, car la fusion des deux en une seule méthode est légèrement plus efficace.

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);

Mamun
la source
6

Vous pouvez prendre un Array#flatMapavec la propriété recherchée. Si la propriété n'est pas donnée, ajoutez un tableau par défaut || [].

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; }

Nina Scholz
la source
2
Il est bon de mentionner que .flatMap ne fonctionne pas dans Edge et IE sans polyfills.
Zydnar
3

Peut aussi résoudre en utilisant le Réduire la fonction de Array.prototype.

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

J'espère que cela t'aides

skyhavoc
la source
2

J'ai passé trop de temps là-dessus pour ne pas poster ma propre solution - puzzle intéressant pour moi, bien que les autres réponses soient sans aucun doute plus performantes et lisibles. Il utilise le même type de stratégie que votre message d'origine, ce qui pourrait aider à indiquer où il a mal tourné.

const locationIds = [].concat
                    .apply([], results.filter(result => 
                    result.locations && result.locations.length > 0)
                    .map(result => { return result.locations }));
Lawrence-Witt
la source