在数组中添加对象的属性,并通过loadash获取单个对象

时间:2017-05-09 11:21:09

标签: javascript arrays json lodash

我在项目中使用了loadash 我有像这样的数组对象

[{
    "rating": {
        "time_to_table": 5,
        "value_for_money": 5,
        "innovation": 5,
        "plating_decoration": 5,
        "taste": 5
    }
}, {
    "rating": {
        "time_to_table": 0,
        "value_for_money": 3,
        "innovation": 2,
        "plating_decoration": 2,
        "taste": 4
    }
}]

现在我希望通过添加每个属性来输出这样的输出,并希望像这样的单个对象

"rating": {
    "time_to_table": 5,
    "value_for_money": 8,
    "innovation": 7,
    "plating_decoration": 7,
    "taste": 9
}

我试过这个

        var obj = {
            "time_to_table": 0,
            "value_for_money": 0,
            "innovation": 0,
            "plating_decoration": 0,
            "taste": 0,
            "total" : 5 * data.length
        }

        _.forEach(data,function(d){          
            obj.time_to_table += d.rating.time_to_table;
            obj.value_for_money += d.rating.value_for_money;
            obj.innovation += d.rating.innovation;
            obj.plating_decoration += d.rating.plating_decoration;
            obj.taste += d.rating.taste;
        });

5 个答案:

答案 0 :(得分:1)

使用Lodash,您可以使用自定义函数作为参数的reduce()mergeWith()来执行此操作。



var data = [{"rating":{"time_to_table":5,"value_for_money":5,"innovation":5,"plating_decoration":5,"taste":5}},{"rating":{"time_to_table":0,"value_for_money":3,"innovation":2,"plating_decoration":2,"taste":4}}]

var result = _.reduce(data, function(r, e, i) {
  if(i != 0) _.mergeWith(r.rating, e.rating, (a, b) => a + b)
  return r;
}, data[0])

console.log(result)

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您可以使用Array#reduce()Object.keys()

执行此操作

const data = [{rating:{time_to_table:5,value_for_money:5,innovation:5,plating_decoration:5,taste:5}},{rating:{time_to_table:0,value_for_money:3,innovation:2,plating_decoration:2,taste:4}}];

let finalObject = data.reduce((o, c) => {
  Object.keys(c.rating).forEach(k => {
    o.rating[k] = o.rating[k] || 0;
    o.rating[k] += c.rating[k];
  });
  return o;
}, { rating: {} })

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

答案 2 :(得分:0)

您可以使用reduce,并在对象中拥有任意数量的属性。

以下函数不需要知道您传递的对象类型,因为没有硬编码属性

const arr = [{
    "rating": {
        "time_to_table": 5,
        "value_for_money": 5,
        "innovation": 5,
        "plating_decoration": 5,
        "taste": 5
    }, 
    a: {b: 1, c: 2}
}, {
    "rating": {
        "time_to_table": 0,
        "value_for_money": 3,
        "innovation": 2,
        "plating_decoration": 2,
        "taste": 4
    },
    a: {b: 3, c: 0}
}];

const result = arr.reduce(fn, {})

function fn (acc, val) {
  for (let x in val) {
    acc[x] = acc[x] || {};
    for (let y in val[x]) {
      acc[x][y] = acc[x][y] || 0;
      acc[x][y] += val[x][y];
    }
  }
  
  return acc;
}

console.log(result)

答案 3 :(得分:0)

Array#reduce解决方案。

var arr = [{"rating":{"time_to_table":5,"value_for_money":5,"innovation":5,"plating_decoration":5,"taste":5}},{"rating":{"time_to_table":0,"value_for_money":3,"innovation":2,"plating_decoration":2,"taste":4}}], obj = arr[0]; arr.splice(0,1);

var res = arr.reduce(function(s, a) {
  Object.keys(a.rating).forEach(function(v) {
    s.rating[v] += a.rating[v];
  })
  return s;
}, obj);

console.log(res);

答案 4 :(得分:0)

您可以对任意嵌套对象使用递归方法,以收集和汇总对象中的值。

var data = [{ rating: { time_to_table: 5, value_for_money: 5, innovation: 5, plating_decoration: 5, taste: 5 } }, { rating: { time_to_table: 0, value_for_money: 3, innovation: 2, plating_decoration: 2, taste: 4 } }],
    result = data.reduce(function iter(target, source) {
        Object.keys(source).forEach(function (k) {
            if (source[k] && typeof source[k] === 'object') {
                iter(target[k] = target[k] || {}, source[k]);
                return;
            }
            target[k] = (target[k] || 0) + +source[k];
        });
        return target;
    }, {});

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