获取对象中的重复项并合并值

时间:2018-09-24 13:49:12

标签: javascript node.js underscore.js

我有一个非常简单的问题,我只是想不通。

我想合并所有重复的对象,并跟踪我有多少个重复对象。

这是我的输入内容:

[
  { w: 'abc', c: 1 },
  { w: 'abc', c: 1 },
  { w: 'abc', c: 1 },
  { w: 'a', c: 1 },
  { w: 'a', c: 1 },
  { w: 'b', c: 1 },
  { w: 'c', c: 1 }
]

这是我想要的输出,

[ 
  { w: 'abc', c: 3 },
  { w: 'a', c: 2 },
  { w: 'b', c: 1 },
  { w: 'c', c: 1 }
]

_.union()可以删除重复项,但我无法跟踪它们。

非常感谢您的帮助。

5 个答案:

答案 0 :(得分:1)

您可以链接下划线的方法,并按w对项目进行分组,然后将新对象与所需值的总和映射。

var data = [{ w: 'abc', c: 1 }, { w: 'abc', c: 1 }, { w: 'abc', c: 1 }, { w: 'a', c: 1 }, { w: 'a', c: 1 }, { w: 'b', c: 1 }, { w: 'c', c: 1 }],
    result = _
        .chain(data)
        .groupBy('w')
        .map((array, w) => ({ w, c: _.reduce(array, (s, { c }) => s + c, 0) }))
        .value();

    console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

答案 1 :(得分:0)

这是使用纯JavaScript的O(n)解决方案。

var arr = [ { w: 'abc', c: 1 },
{ w: 'abc', c: 1 },
{ w: 'abc', c: 1 },
{ w: 'a', c: 1 },
{ w: 'a', c: 1 },
{ w: 'b', c: 1 },
{ w: 'c', c: 1 }];

var tempObj = {};
arr.forEach((obj)=>{
  if(tempObj[obj.w]){
    tempObj[obj.w].c += obj.c
  } else {
    tempObj[obj.w] = {
      w: obj.w,
      c : obj.c
    }
  }
});
var resArray = Object.values(tempObj);
console.log(resArray);

答案 2 :(得分:0)

您可以映射并缩小它以获得所需的数据:

const data = [ { w: 'abc', c: 1 },
{ w: 'abc', c: 1 },
{ w: 'abc', c: 1 },
{ w: 'a', c: 1 },
{ w: 'a', c: 1 },
{ w: 'b', c: 1 },
{ w: 'c', c: 1 }]


const output = data
  .map(item => item.w)
  .reduce((prev, curr) => ({
    ...prev,
    [curr]: (prev[curr] || 0) + 1
  }), {})
  
const correctFormat = Object.keys(output)
  .map(key => ({
    w: key,
    c: output[key]
  }))
  
console.dir(correctFormat)

答案 3 :(得分:0)

您应该使用Array.protoype.reduce方法。您可以传递一个空的对象常量作为第二个参数,并根据每个数组元素的w属性向其添加键。对于数组的每个元素,检查键是否已经存在-如果不存在,则将计数设置为1-如果存在,则将计数增加1:

var a = [{
    w: 'abc',
    c: 1
  },
  {
    w: 'abc',
    c: 1
  },
  {
    w: 'abc',
    c: 1
  },
  {
    w: 'a',
    c: 1
  },
  {
    w: 'a',
    c: 1
  },
  {
    w: 'b',
    c: 1
  },
  {
    w: 'c',
    c: 1
  }
];

var b = a.reduce((accum, el) => {
  if (accum[el.w]) {
    accum[el.w] = accum[el.w] + 1;
  } else {
    accum[el.w] = 1;
  }
  return accum;
}, {});

console.log(b);

这是标准的JavaScript解决方案-不需要利用下划线功能。

答案 4 :(得分:0)

这是使用_.countBy()_.map的另一种方法:

var data = [ { w: 'abc', c: 1 },
    { w: 'abc', c: 1 },
    { w: 'abc', c: 1 },
    { w: 'a', c: 1 },
    { w: 'a', c: 1 },
    { w: 'b', c: 1 },
    { w: 'c', c: 1 }]


var result = _
  .chain(data)
  .countBy('w')
  .map(function(v, k) {  
    return { w: k, c: v }
  })
  .value();

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>