Estoy tratando de agrupar objetos que tienen la misma propiedad juntos. Estoy comenzando con una matriz de objetos, y quiero terminar con una matriz que contiene varias matrices, cada una con los objetos que comparten la misma propiedad.

Digamos que tengo esta variedad de objetos de película, todos tienen una propiedad de año, y quiero agrupar todas las películas con la misma propiedad de año en su propia matriz y finalmente tener todas esas matrices en una sola matriz.

// This is the array I've got
const films = [
  {
    name='film 1',
    year='1992'
  },
  {
    name='film 2',
    year='1992'
  },
  {
    name='film 3',
    year='1995'
  },
  {
    name='film 4',
    year='1995'
  },
  {
    name='film 5',
    year='1995'
  },
  {
    name='film 6',
    year='1998'
  },
  {
    name='film 7',
    year='1998'
  },
]

// And this is the array I want to end up with
const filmsSorted = [
  [
    {
      name='film 1',
      year='1992'
    },
    {
      name='film 2',
      year='1992'
    },
  ]
  [
    {
      name='film 3',
      year='1995'
    },
    {
      name='film 4',
      year='1995'
    },
    {
      name='film 5',
      year='1995'
    },
  ]
  [
    {
      name='film 6',
      year='1998'
    },
    {
      name='film 7',
      year='1998'
    },
  ]
]

Tenga en cuenta que no tengo la propiedad year por adelantado y debo tratar de manera dinámica con cualquier año que reciba en la matriz original.

Si bien hay muchas preguntas sobre la ordenación y el filtrado de matrices aquí, no pude encontrar una respuesta a este problema específico. Traté de usar reduce() y filter() y una combinación de ellos, pero parece que no puedo entenderlo. He encontrado algunas soluciones posibles (transformándolo en un objeto y nuevamente en una matriz), pero lo que realmente me gustaría es ver algunas formas diferentes de resolver esto para ayudarme a razonar mejor.

0
Syknapse 27 oct. 2019 a las 13:34

3 respuestas

La mejor respuesta

Simplemente tome una tabla hash y agrupe por year y tome los valores de la tabla hash.

Bonificación: Un resultado ordenado, porque las claves del objeto están ordenadas, si las claves pueden leerse como índices de una matriz.

var films = [{ name: 'film 1', year: '1992' }, { name: 'film 2', year: '1992' }, { name: 'film 3', year: '1995' }, { name: 'film 4', year: '1995' }, { name: 'film 5', year: '1995' }, { name: 'film 6', year: '1998' }, { name: 'film 7', year: '1998' }],
    grouped = Object.values(
        films.reduce((r, o) => {
            (r[o.year] = r[o.year] || []).push(o);
            return r;
        }, {})
    );

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
2
Nina Scholz 27 oct. 2019 a las 10:49

He encontrado otra forma de hacerlo, lo dejaré aquí en caso de que sea útil para futuros lectores.

const films = [{ name: 'film 1', year: '1992' }, { name: 'film 2', year: '1992' }, { name: 'film 3', year: '1995' }, { name: 'film 4', year: '1995' }, { name: 'film 5', year: '1995' }, { name: 'film 6', year: '1998' }, { name: 'film 7', year: '1998' }]
let filmsSorted = []
let years = {}

films.forEach(film => {
    if (!years[film.year]) years[film.year] = []
    years[film.year].push(film)
})

filmsSorted = Object.values(years)

Esto crea un objeto intermedio, que tiene pares clave / valor de las propiedades comunes (años) y matrices de todos los objetos que contienen esta propiedad. Luego, simplemente podemos crear una matriz de valores y terminamos con la clasificación requerida.

0
Syknapse 4 nov. 2019 a las 10:16

Prueba esto:

const films = [
  {
    name: 'film 1',
    year: '1992'
  },
  {
    name: 'film 2',
    year: '1992'
  },
  {
    name: 'film 3',
    year: '1995'
  },
  {
    name: 'film 4',
    year: '1995'
  },
  {
    name: 'film 5',
    year: '1995'
  },
  {
    name: 'film 6',
    year: '1998'
  },
  {
    name: 'film 7',
    year: '1998'
  }
]

const result = films.reduce((acc, curr) => {
  if (acc.some(e => e[0].year === curr.year)) acc.filter(e => e[0].year === curr.year)[0].push(curr)
  else acc.push([curr])
  
  return acc
}, [])

console.log(result)
1
cherryblossom 27 oct. 2019 a las 10:52