对javascript对象数组进行分组和排序

时间:2016-01-29 13:16:58

标签: javascript arrays

给出以下虚拟数据源:

// Dummy data source
var dbCustomerOrderItems = [];
dbCustomerOrderItems.push({ 
    Items: JSON.stringify([{ Sku: 'ABC1', Name: 'Name 1', Ordered: 1}])
});
dbCustomerOrderItems.push({ 
    Items: JSON.stringify([{ Sku: 'ABC2', Name: 'Name 2', Ordered: 3}])
});
dbCustomerOrderItems.push({ 
    Items: JSON.stringify([{ Sku: 'ABC2', Name: 'Name 2', Ordered: 1}])
});

我把它解析成一个像这样的线性对象数组:

// Init list
var popularProducts = [];

// Iterate throug customer orders
for (var i = 0; i < dbCustomerOrderItems.length; i++)
{
    // Parse items data
    try
    {
        var itemsData = JSON.parse(dbCustomerOrderItems[i].Items);
        for (var j = 0; j < itemsData.length; j++)
        {
            popularProducts.push({
                Name: itemsData[j].Sku +' | '+ (typeof itemsData[j].Name !== 'undefined' ? itemsData[j].Name : 'Product name not available'),
                Quantity: parseInt(itemsData[j].Ordered)
            });
        }
        itemsData = null;
    }
    catch (e) { }
}

// Debug
console.log(popularProducts);

其中输出以下内容:

enter image description here

我想对这个对象数组做的是:

1)按Name对数组进行分组,因此合并后的数据如下所示:

var groupedPopularProducts = [
    { Name: 'ABC1 | Name 1', Quantity: 1 },
    { Name: 'ABC2 | Name 2', Quantity: 4 }
];

2)然后我想按groupedPopularProducts降序排序Quantity。因此得到的数组如下所示:

var sortedPopularProducts = [
    { Name: 'ABC2 | Name 2', Quantity: 4 },
    { Name: 'ABC1 | Name 1', Quantity: 1 }
];

我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:1)

将元素分组为类似对象的字典,并将其排序为具有自定义比较函数的数组。

var groupedProducts = {};

// grouping
for(var i=0;i<popularProducts.length;i++) {
    if (!(popularProducts[i].Name in groupedProducts)) {
        groupedProducts[popularProducts[i].Name] = popularProducts[i];
    }
    else {
        groupedProducts[popularProducts[i].Name].Quantity += popularProducts[i].Quantity;
    }
}

// sorting
var groupedProductsList = Object.keys(groupedProducts).map(function (key) {return groupedProducts[key]});

groupedProductsList.sort(function (a,b) {
    return b.Quantity - a.Quantity;
})


// Debug
console.log(groupedProductsList);

<强>输出:

[ { Name: 'ABC2 | Name 2', Quantity: 4 },
 { Name: 'ABC1 | Name 1', Quantity: 1 } ]

答案 1 :(得分:0)

您可以尝试这样的事情:

var data = [
    { Name: 'ABC1 | Name 1', Quantity: 1 },
    { Name: 'ABC2 | Name 2', Quantity: 3 },
    { Name: 'ABC2 | Name 2', Quantity: 1 }];

var obj = {};
var result = [];
var _temp = [];

data.forEach(function(item){
  if(!obj[item.Name])
    obj[item.Name] = {
      Name:item.Name,
      Quantity:0
    };
  
  obj[item.Name].Quantity += item.Quantity;
});

for(var key in obj){
  _temp.push(obj[key]);
}

result = _temp.sort(function(a,b){
  return b.Quantity - a.Quantity
});

console.log(result)

答案 2 :(得分:0)

具有一次迭代和临时对象的解决方案。

&#13;
&#13;
var dbCustomerOrderItems = [{ Items: JSON.stringify([{ Sku: 'ABC1', Name: 'Name 1', Ordered: 1 }]) }, { Items: JSON.stringify([{ Sku: 'ABC2', Name: 'Name 2', Ordered: 3 }]) }, { Items: JSON.stringify([{ Sku: 'ABC2', Name: 'Name 2', Ordered: 1 }]) }],
    result = dbCustomerOrderItems.reduce(function (r, a) {
        var o = JSON.parse(a.Items)[0],
            k = o.Sku + ' | ' + o.Name;
        if (!(k in r.obj)) {
            r.obj[k] = { Name: k, Quantity: 0 };
            r.array.push(r.obj[k]);
        }
        r.obj[k].Quantity += o.Ordered;
        return r;
    }, { array: [], obj: {} }).array.sort(function (a, b) { return b.Quantity - a.Quantity; });

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
&#13;
&#13;
&#13;