lodash对象数组的总和

时间:2017-12-02 05:40:02

标签: javascript lodash

我刚刚开始学习lodash,并尝试将其合并到我的代码中。正如您所看到的,我正在添加员工下每个元素的权重。我遇到的问题是我不知道如何获得第三个元素"性别"进入我最后的数据数组。我使用这个Reduce array of objects on key and sum value into array来构造我的lodash代码。您可以在下面看到我如何尝试获取输出。



var userAns = [{
    id: 1,
    text: "answer1",
    employee: [{
        name: "John",
        weight: 3,
        gender: "male"
      },
      {
        name: "Sally",
        weight: 4,
        gender: "female"
      }
    ]
  },
  {
    id: 2,
    text: "answer2",
    employee: [{
        name: "John",
        weight: 6,
        gender: "male"
      },
      {
        name: "Sally",
        weight: 3,
        gender: "female"
      }
    ]
  }
];

var scores = [];
for (var i = 0; i < userAns.length; i++) {
  for (var j = 0; j < userAns[i].employee.length; j++) {
    scores.push(userAns[i].employee[j]);
  }
}

var result = _(scores)
  .map('name')
  .uniq()
  .map(function(key) {

    return {
      name: key,
      score: _(scores).filter({
        name: key
      }).sumBy('weight')
    };
  })
  .value();

console.log(result);
&#13;
<script src="https://cdn.jsdelivr.net/lodash/4.14.1/lodash.min.js"></script>
&#13;
&#13;
&#13;

以下是我尝试获取数组的方法

&#13;
&#13;
[
  {
    "name": "John",
    "score": 9,
    "gender": "male"
  },
  {
    "name": "Sally",
    "score": 7,
    "gender":"female" 
  }
]
&#13;
&#13;
&#13;

4 个答案:

答案 0 :(得分:1)

您可以使用lodash find方法,然后使用pluck您想要从Object获取的密钥,并使用values获取对象的值,并将其分配给性别密钥最终的结果对象

&#13;
&#13;
var userAns = [{
    id: 1,
    text: "answer1",
    employee: [{
        name: "John",
        weight: 3,
        gender: "male"
      },
      {
        name: "Sally",
        weight: 4,
        gender: "female"
      }
    ]
  },
  {
    id: 2,
    text: "answer2",
    employee: [{
        name: "John",
        weight: 6,
        gender: "male"
      },
      {
        name: "Sally",
        weight: 3,
        gender: "female"
      }
    ]
  }
];

var scores = [];
for (var i = 0; i < userAns.length; i++) {
  for (var j = 0; j < userAns[i].employee.length; j++) {
    scores.push(userAns[i].employee[j]);
  }
}

var result = _(scores)
  .map('name')
  .uniq()
  .map(function(key) {
    return {
      name: key,
      gender: _.values(_.pick(_.find(scores, (d) => d.name == key),'gender'))[0],
      score: _(scores).filter({
        name: key
      }).sumBy('weight')
    };
  })
  .value();

console.log(result);
&#13;
<script src="https://cdn.jsdelivr.net/lodash/4.14.1/lodash.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

你可以在没有lodash的情况下完成这个任务。您可以使用array#reduce首先在每个employee内累积所有userAns数组,然后再使用array#reduce来总结weight。然后,使用Object.values()

获取输出

&#13;
&#13;
var userAns = [{ id: 1, text: "answer1", employee: [{ name: "John", weight: 3, gender: "male" }, { name: "Sally", weight: 4, gender: "female" } ] }, { id: 2, text: "answer2", employee: [{ name: "John", weight: 6, gender: "male" }, { name: "Sally", weight:3, gender: "female" }]}];

var result = userAns
              .reduce((r,o) => r.concat(o.employee),[])
              .reduce((r,o) => {
                  if(r[o.name])
                      r[o.name].weight += o.weight;
                  else
                    r[o.name] = o;
                  return r;
              },{});
              
var output = Object.values(result);
console.log(output);
&#13;
&#13;
&#13;

答案 2 :(得分:1)

使用lodash:

您可以结合使用_.flatMap()_.groupBy()_.map()_.mergeWith()

&#13;
&#13;
var userAns = [{"id":1,"text":"answer1","employee":[{"name":"John","weight":3,"gender":"male"},{"name":"Sally","weight":4,"gender":"female"}]},{"id":2,"text":"answer2","employee":[{"name":"John","weight":6,"gender":"male"},{"name":"Sally","weight":3,"gender":"female"}]}];

var result = _(userAns)
  .flatMap('employee') // create an array of all emplyoees
  .groupBy('name') // create groups of employees with the same name
  .map(function(g) {
    // merge each group to a single object, and combine weight values
    return _.mergeWith.apply(_, [{}].concat(g, function(obj, src, key) {
      return key === 'weight' ? (obj || 0) + src : undefined;
    }));
  })
  .value();
  
console.log(result);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
&#13;
&#13;
&#13;

使用ES6:

使用Array#map获取employee数组数组,并将spreading展平为Array#concatReduce将数组放入Map,然后通过传播Map#values迭代器转换回数组:

&#13;
&#13;
const userAns = [{"id":1,"text":"answer1","employee":[{"name":"John","weight":3,"gender":"male"},{"name":"Sally","weight":4,"gender":"female"}]},{"id":2,"text":"answer2","employee":[{"name":"John","weight":6,"gender":"male"},{"name":"Sally","weight":3,"gender":"female"}]}];

const result = [...
  [].concat(...userAns.map(({ employee }) => employee)) // combine all employees to a single array
  .reduce((m, o) => { // reduce similar employees to a single object in a Map, and combine weight
    // if the name object doesn't exists create a new one by cloning the object, and assigning weight: 0
    m.has(o.name) || m.set(o.name, Object.assign({}, o, { weight: 0 }));
    
    m.get(o.name).weight += o.weight; // add the current weight to the name object
    
    return m;
  }, new Map())
  .values()]; // get the Map values, and spread to convert to array
  
console.log(result);
&#13;
&#13;
&#13;

答案 3 :(得分:0)

您可以通过稍作修改来完成此操作。首先让您的用户进入map,如下所示

var user = _(scores).filter({
  name: key
});

然后,您可以从中提取得分的总和和性别

return {
  name: key,
  score: user.sumBy('weight'),
  gender: user.get('[0]').gender
};

请在下面找到修改后的代码段

&#13;
&#13;
var userAns = [{
  id: 1,
  text: "answer1",
  employee: [{
    name: "John",
    weight: 3,
    gender: "male"
  }, {
    name: "Sally",
    weight: 4,
    gender: "female"
  }]
}, {
  id: 2,
  text: "answer2",
  employee: [{
    name: "John",
    weight: 6,
    gender: "male"
  }, {
    name: "Sally",
    weight: 3,
    gender: "female"
  }]
}];

var scores = [];
for (var i = 0; i < userAns.length; i++) {
  for (var j = 0; j < userAns[i].employee.length; j++) {
    scores.push(userAns[i].employee[j]);
  }
}


var result = _(scores)
  .map('name')
  .uniq()
  .map(function(key) {
    var user = _(scores).filter({
      name: key
    });
    return {
      name: key,
      score: user.sumBy('weight'),
      gender: user.get('[0]').gender
    };
  })
  .value();

console.log(result);
&#13;
<script src="https://cdn.jsdelivr.net/lodash/4.14.1/lodash.min.js"></script>
&#13;
&#13;
&#13;