Combinar matrices en una matriz después de filtrar


14

Tengo una variedad de objetos, donde solo tomo ubicaciones. Mi objetivo es fusionar estas ubicaciones en una matriz, sin embargo, no lo hago y obtengo una matriz vacía. Así es como lo hago:

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

¿Qué estoy haciendo mal aquí? El resultado debería ser ['aaaa', 'bbbbbb', 'cccccc', 'ddd', 'aaadsad', 'sefd', 'ffff', 'eeee', 'sfdsfsd'];

Respuestas:


9

No necesitas filteraquí. Simplemente utilice el mapmétodo pasando una función de devolución de llamada que se aplica para cada elemento de la matriz.

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, de nada! Puede crear su propia implementación flatMapcomo aquí: stackoverflow.com/questions/39837678/…
Mihai Alexandru-Ionut

7

Puedes probar con flatMap():

El flatMap()método primero mapea cada elemento usando una función de mapeo, luego aplana el resultado en una nueva matriz. Es idéntico a un map()seguido de un flat()de profundidad 1 , pero a flatMap()menudo es bastante útil, ya que fusionar ambos en un método es un poco más eficiente.

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

Podrías taka a Array#flatMapcon la propiedad deseada. Si no se proporciona la propiedad, agregue una matriz predeterminada || [].

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
Es bueno mencionar que .flatMap no funciona en Edge e IE sin polyfills.
Zydnar

3

También se puede resolver usando la función Reducir de Array.prototype.

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

espero que esto ayude


2

Pasé demasiado tiempo en esto para no publicar mi propia solución, un rompecabezas interesante para mí, aunque las otras respuestas son sin duda más efectivas y legibles. Utiliza el mismo tipo de estrategia que su publicación original, lo que podría ayudar a señalar dónde salió mal.

const locationIds = [].concat
                    .apply([], results.filter(result => 
                    result.locations && result.locations.length > 0)
                    .map(result => { return result.locations }));
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.