Estoy tratando de encontrar la forma más fácil de tomar una matriz que tenga información similar y crear una matriz con una matriz secundaria. La matriz primaria recién creada también debe sumar los valores que se encuentran en la submatriz. Este es el equivalente de una instrucción SQL que usa sum / group by.

Esta es la matriz original.

[
    {
        'userId':1,
        'userName':'bob',
        'category':'shoes',
        'count':2
    },
    {
        'userId':1,
        'userName':'bob',
        'category':'rocks',
        'count':4
    },
    {
        'userId':1,
        'userName':'bob',
        'category':'bags',
        'count':3
    },
    {
        'userId':2,
        'userName':'sue',
        'category':'shoes',
        'count':1
    },
    {
        'userId':2,
        'userName':'sue',
        'category':'rocks',
        'count':7
    },
    {
        'userId':2,
        'userName':'sue',
        'category':'bags',
        'count':4
    },
]

Así es como quiero que se vea la matriz recién creada:

[
    {
        'userId':1,
        'userName':'bob',
        'purchases': [
            {'category':'shoes','count':'2'},
            {'category':'rocks','count':'4'},
            {'category':'bags','count':'3'}
        ],
        'totalCount' : 9
    },
    {
        'userId':2,
        'userName':'sue',
        'purchases': [
            {'category':'shoes','count':'1'},
            {'category':'rocks','count':'7'},
            {'category':'bags','count':'4'}
        ],
        'totalCount' : 12
    },  
]
0
Meeker 5 sep. 2014 a las 02:36

2 respuestas

La mejor respuesta

Primero groupBy userId y luego mapear los grupos para obtener la estructura deseada:

    var groups = _.groupBy(list, 'userId');

    var result = _.map(groups, function(user){
        return {
            userId: user[0].userId,
            userName: user[0].userName,
            purchases: _.map(user, function(purchase){
                return {
                    category: purchase.category,
                    count: purchase.count
                }
            }),
            totalCount: _.reduce(user, function(memo, purchase){
                return memo + purchase.count;
            }, 0)
        }
    });
1
Gruff Bunny 5 sep. 2014 a las 01:21

Puede hacerlo con Alasql biblioteca SQL JavaScript:

Esto es un ejemplo:

var res = alasql('SELECT userId, FIRST(userName) as userName, \
                     ARRAY({category:category,[count]:[count]}) AS purchases,\
                     SUM([count]) AS totalCount FROM ? GROUP BY userId',[data]);

Pruebe este ejemplo en jsFiddle. Compare la velocidad con la solución Lodash 'en jsPerf.

Comentarios:

  1. Puse [count] entre corchetes, porque COUNT es una palabra clave reservada de SQL
  2. El agregador ARRAY () produce una matriz con valores
0
agershun 22 dic. 2014 a las 03:50