Underscore.js将对象转换为数组

时间:2014-09-16 11:00:33

标签: javascript arrays object underscore.js

我对underscore.js相对较新,我有一个来自REST服务的对象,看起来像这样(我手动输入并将其分配给var):

var production = [
    {key: ["wind", "1"], value: 5},
    {key: ["wind", "2"], value: 9},
    {key: ["wind", "3"], value: 11},
    {key: ["wind", "4"], value: 7},
    {key: ["solar", "1"], value: 1},
    {key: ["solar", "2"], value: 1},
    {key: ["solar", "3"], value: 2},
    {key: ["solar", "4"], value: 3},
    {key: ["oil", "1"], value: 15},
    {key: ["oil", "2"], value: 16},
    {key: ["oil", "3"], value: 22},
    {key: ["oil", "4"], value: 23},
];

然后再往下,我有一些代码可以解析这个对象,并为这样的项创建数组:

var orderedProduction = _.chain(production)
      .groupBy(function (entity) {
            return entity.key[0];
      })
      .map(function (values) { 
            return _.map(values, function (entity2) {
                  return entity2.value;
            });
      })
      .value();

这给出了以下结果:

orderedProduction  = [
  [5, 9, 11, 7],
  [1, 1, 2, 3],
  [15, 16, 22, 23]
]

失去钥匙(风/太阳能/油)。并用于绘制图形。我还能够检查其中一些阵列是否达到某个阈值,如下所示:

var threshold = _.map(orderedProduction  , function(arr) {
    return _.max(arr) > 10;
});

我的要求现在已经改变,我现在需要按总和来过滤掉这些数组,同时保留密钥。

我想最终得到一个像这样的对象:

orderedProduction  = {
      "wind": [5, 9, 11, 7],
      "solar": [1, 1, 2, 3],
      "oil": [15, 16, 22, 23]
    }

如果修复程序包含一种总结数组值的方法并删除那些不总计达到一定数量的数组,那将会很棒。 (即排除太阳能,如果它不加10)。

这是我创建的一个jsfiddle来测试这一切:http://jsfiddle.net/2mfjw3jk/


更新: 我解决的解决方案是:

var orderedProduction = _.chain(production)
    .groupBy(function (entity) {
        return entity.key[0];
    })
    .map(function (vals, key) {
        return [key, _.pluck(vals, 'value')]
    })
    .filter(function(arr) {
        var sum = 0;
        _.each(arr[1], function(num){
            sum += num;
        })
        return sum > 10;
    })
    .object()
    .value();

它还会将值过滤预定的阈值(在这种情况下为10)。

3 个答案:

答案 0 :(得分:7)

你快到了:

var orderedProduction = _.chain(production)
    .groupBy(function (entity) {
        return entity.key[0];
    })
    .map(function (vals, key) {
        return [key, _.pluck(vals, 'value')]
    })
    .object()
    .value();

返回

{ wind: [ 5, 9, 11, 7 ],
  solar: [ 1, 1, 2, 3 ],
  oil: [ 15, 16, 22, 23 ] }

答案 1 :(得分:2)

您可以简单地使用javascript中提供的map()函数。给出的_.map()是为了向后兼容。 无论如何,这是代码:

var obj = {};
production.map(function(data) {
    if(data.key[0] in obj) {
        obj[data.key[0]] += data.value;
    } else {
        obj[data.key[0]] = 0;
        obj[data.key[0]] += data.value;
    }
});
console.log(obj);

那么它是如何循环生产数组的呢。在那里,它检查密钥(例如,“密钥”是否是密钥)是否在obj对象中。如果它在那里,那么它只是增加它的值或者创建一个新的密钥并将其赋值为0然后递增它。

不是最优化的代码,但效果很好。

答案 2 :(得分:1)

这可能不是性能最佳的代码,但它可以使用下划线完成工作。

Live Demo

var production = [
    {key: ["wind", "1"], value: 5},
    {key: ["wind", "2"], value: 9},
    {key: ["wind", "3"], value: 11},
    {key: ["wind", "4"], value: 7},
    {key: ["solar", "1"], value: 1},
    {key: ["solar", "2"], value: 1},
    {key: ["solar", "3"], value: 2},
    {key: ["solar", "4"], value: 3},
    {key: ["oil", "1"], value: 15},
    {key: ["oil", "2"], value: 16},
    {key: ["oil", "3"], value: 22},
    {key: ["oil", "4"], value: 23}
];

var orderedProduction =  _.chain(production)
    .groupBy(function (entity) {
        return entity.key[0];
    })
    .map(function(items, key){
        var returnVal = [key]; 
        var total = 0; 
        returnVal.push(_.map(items, function(obj){
            total += obj.value; 
            return obj.value; 
        })); 

        if(total > 10){
            return returnVal; 
        }

    })
    .filter(function(num) {
        return num !== undefined;
    })
    .object()
    .value();

console.log(production);
console.log(orderedProduction);