在JavaScript中的新数组中对具有确定值的对象键进行分组

时间:2017-04-12 10:07:22

标签: javascript arrays

我有一个像这样的对象数组:

[
{
    item: 'abc',
    category: 'car',
    price: 1000
},
{
    item: 'abc',
    category: 'bike',
    price: 1000
},
{
    item: 'abc',
    category: 'car',
    price: 2000
},
{
    item: 'abc',
    category: 'car',
    price: 3000
},
{
    item: 'abc',
    category: 'bike',
    price: 500
},
{
    item: 'abc',
    category: 'plane',
    price: 9000
},

我想从上面的数组创建一个新的数组,它按类别对​​对象进行分组,并将该类别的总价格作为“价格”键的值:

[
{
    category: car,
    price: 6000
},
{
    category: bike,
    price: 1500
},
{
    category: plane,
    price: 9000
}

如何在Javascript中执行此操作?

4 个答案:

答案 0 :(得分:2)

基本方法是

  • 首先创建一个地图,其中类别为关键,价格为值
  • 将此地图转换为数组

DEMO



var input = [
{
    item: 'abc',
    category: 'car',
    price: 1000
},
{
    item: 'abc',
    category: 'bike',
    price: 1000
},
{
    item: 'abc',
    category: 'car',
    price: 2000
},
{
    item: 'abc',
    category: 'car',
    price: 3000
},
{
    item: 'abc',
    category: 'bike',
    price: 500
},
{
    item: 'abc',
    category: 'plane',
    price: 9000
},
];

var map = {};
input.forEach( function ( item ){
  map [ item.category ] = map [ item.category ] || 0;
  map [ item.category ] += item.price;
});
var output = Object.keys( map ).map( function(key){ return { category: key, price : map[key] } });

console.log( output );




答案 1 :(得分:1)

您可以使用哈希表对其进行分组,并将其作为添加值的参考。

  

主要结构:

grouped = data.reduce(function (hash) {    // closure over hash
    return function (r, a) { /* ... */ };  // returns function for callback
}(Object.create(null)), []);               // call of IFFE with an empty object
     

主要思想是在全局上下文之外使用变量hash,但可以在Array#reduce的回调中使用。

     

这适用于IIFE(立即调用函数表达式),这是一个直接在用空对象调用声明之后的函数。

     

这将创建一个带有空对象的变量hash,并返回回调函数。

     

回调内部:

     

回调适用于两个变量ra

function (r, a) {
    // business logic
    return r;
}
     

开始时,变量r获取空数组[]的{​​{3}}。在此数组中,将收集结果集并在每次迭代时返回结果集。此参数描述为累加器。

     

参数a是数组的当前值。这是一个单个对象,比如

{
    item: 'abc',
    category: 'car',
    price: 1000
}
     

并且只有一个对象同时被处理。

     

基本上这个解决方案适用于一个对象,它看起来就像这样

{
    car: {
        category: "car",
        price: 6000
    },
    bike: {
        category: "bike",
        price: 1500
    },
    plane: {
        category: "plane",
        price: 9000
    }
}
     

其中属性(如carbike)提供对结果数组的引用,而不包含属性carbike

     

首先,如果哈希表中存在类别,则进行检查。如果没有,则创建一个新对象categoryprice为零,因为price属性会针对同一类别中的每个项目进行更新。然后新的对象引用被推送到结果数组。

     

检查后,属性已经存在或刚刚创建,price属性将获得具有实际值的更新。

     

最后,返回结果集以进行下一次更新迭代或作为最终结果。

var data = [{ item: 'abc', category: 'car', price: '1000' }, { item: 'abc', category: 'bike', price: '1000' }, { item: 'abc', category: 'car', price: '2000' }, { item: 'abc', category: 'car', price: '3000' }, { item: 'abc', category: 'bike', price: '500' }, { item: 'abc', category: 'plane', price: '9000' }],
    grouped = data.reduce(function (hash) {
        return function (r, a) {
            if (!hash[a.category]) {
                hash[a.category] = { category: a.category, price: 0 };
                r.push(hash[a.category]);
            }
            hash[a.category].price += +a.price;
            return r;
        };
    }(Object.create(null)), []);

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

答案 2 :(得分:1)

var data = [{item: 'abc',category: 'car',price: 1000},{item:'abc',category: 'bike',price: 1000},{item: 'abc',category: 'car',price: 2000},{item: 'abc',category: 'car',price: 3000},{item: 'abc',category: 'bike',price: 500},{item: 'abc',category: 'plane',price: 9000}];

var groupArr = [];
var res = data.reduce(function(all, item, index){
    var i = groupArr.findIndex(x => x.category == item.category);
    if(i <= -1)
        groupArr.push({category: item.category, price: item.price});
    else
        groupArr[i].price += item.price;
        
    return all;
},{})
console.log(groupArr)

答案 3 :(得分:0)

如果这有帮助,请看这个

var obj = [{
  item: 'abc',
  category: 'car',
  price: 1000
}, {
  item: 'abc',
  category: 'bike',
  price: 1000
}, {
  item: 'abc',
  category: 'car',
  price: 2000
}, {
  item: 'abc',
  category: 'car',
  price: 3000
}, {
  item: 'abc',
  category: 'bike',
  price: 500
}, {
  item: 'abc',
  category: 'plane',
  price: 9000
}]

var newobj = {};

obj.forEach(function(record) {
  newobj[record.category] = {
    category: record.category,
    price : newobj[record.category] && newobj[record.category].price ? newobj[record.category].price + record.price : record.price
  }
})
var result = [];
Object.keys(newobj).forEach(function(key) {
    result.push(newobj[key])
})
console.log(result);