仅合并重复出现的重复对象

时间:2018-06-04 10:02:06

标签: javascript arrays ecmascript-6 merge

给定一个数组

[
    {name: 'John', span: 1},
    {name: 'John', span: 1},
    {name: 'Peter', span: 1},
    {name: 'John', span: 1},
    {name: 'Peter', span: 1},
    {name: 'Peter', span: 1},
    {name: 'Peter', span: 1}
]

我想以这样的方式合并它,如果它们重复出现,那么我们合并并总结span属性。所以,预期的输出是

[
    {name: 'John', span: 2},
    {name: 'Peter', span: 1},
    {name: 'John', span: 1},
    {name: 'Peter', span: 3}
]

有人能建议一个合适的方法吗?我能想到的最好的是

var data = [
    {name: 'John', span: 1},
    {name: 'John', span: 1},
    {name: 'Peter', span: 1},
    {name: 'John', span: 1},
    {name: 'Peter', span: 1},
    {name: 'Peter', span: 1},
    {name: 'Peter', span: 1}
];
var result = [];

var count = 0;
while (count <= data.length) {
    var datum = data[count];
    var isFound = false;

    do {
        var nextCount = data[++count];

        if (!nextCount) {
            break;
        }

        if (nextCount.name === datum.name) {
            datum.span += 1;
            isFound = true;
        } else {
            isFound = false;
        }
    } while(isFound);   

    result.push(datum);
}

console.log(result);

除了undefined放在最后(不知道原因)之外,这是有效的。任何人都可以建议一种更有效,更易读的方法吗?

3 个答案:

答案 0 :(得分:1)

这样的事情怎么样:

var data = [
    {name: 'John', span: 1},
    {name: 'John', span: 1},
    {name: 'Peter', span: 1},
    {name: 'John', span: 1},
    {name: 'Peter', span: 1},
    {name: 'Peter', span: 1},
    {name: 'Peter', span: 1}
];

function groupSpans(data) {
    const result = [];
    let current;
    let currentKey;
    data.forEach((datum) => {
        if(datum.name !== currentKey) {
            currentKey = datum.name;
            current = {... datum};
            result.push(current);
            return;
        }
        current.span++;
    });
    return result;
}

console.log(groupSpans(data));

- &GT;

~/Desktop $ node so50677991.js
[ { name: 'John', span: 2 },
  { name: 'Peter', span: 1 },
  { name: 'John', span: 1 },
  { name: 'Peter', span: 3 } ]

答案 1 :(得分:1)

这可能是一个解决方案

const arr = [
  {name: 'John', span: 1},
  {name: 'John', span: 1},
  {name: 'Peter', span: 1},
  {name: 'John', span: 1},
  {name: 'Peter', span: 1},
  {name: 'Peter', span: 1},
  {name: 'Peter', span: 1}
]

const parsed = arr.reduce((acc, item) => {
  if(acc[acc.length - 1] && acc[acc.length - 1].name == item.name) {
    acc[acc.length - 1].span++
  } else {
    acc.push(item)
  }
  return acc
}, [])

console.log(parsed)

答案 2 :(得分:1)

您可以在检查最后一个对象时过滤和更新对象。

此解决方案会改变原始数组。

&#13;
&#13;
var array = [{ name: 'John', span: 1 }, { name: 'John', span: 1 }, { name: 'Peter', span: 1 }, { name: 'John', span: 1 }, { name: 'Peter', span: 1 }, { name: 'Peter', span: 1 }, { name: 'Peter', span: 1 }],
    result = array.filter((last => o => {
        if (!last || last.name !== o.name) {
            last = o;
            return true;
        }
        last.span += o.span;
    })());

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