使用JS map / reduce来合并对象数组而不是forEach

时间:2017-12-06 11:45:52

标签: javascript arrays javascript-objects

我试图学习更好地使用JS函数,我感觉我可以使用reduce或map或两者来完成之后的事情,但我找不到这个特定场景的例子: / p>

我有一个对象数组,例如:

const data =  [
    {
        "member": "111111",
        "offers": 0,
        "categories": 0,
        "total": 100,
        "favorites": 0
    },
    {
        "member": "111111",
        "offers": 2,
        "categories": 1,
        "total": 400,
        "favorites": 1
    },
    {
        "member": "222222",
        "offers": 1,
        "categories": 0,
        "total": 50,
        "favorites": 5
    }
]

目标是减少一个数组,将每个成员的所有键值合并为一个数组,即:

    {
        "member": "111111",
        "offers": 2,
        "categories": 1,
        "total": 500,
        "favorites": 1
    },
    {
        "member": "222222",
        "offers": 1,
        "categories": 0,
        "total": 50,
        "favorites": 5
    },

因此,成员111111有两个条目,它们已合并,所有其他值汇总成一个数组。

老实说,我所尝试的一切都是一团糟,所以除了使用无聊的循环或在这里添加明显垃圾的代码之外,我希望你能指出我正确的方向。

2 个答案:

答案 0 :(得分:3)

你可以做到

const data =  [
    {
        "member": "111111",
        "offers": 0,
        "categories": 0,
        "total": 100,
        "favorites": 0
    },
    {
        "member": "111111",
        "offers": 2,
        "categories": 1,
        "total": 400,
        "favorites": 1
    },
    {
        "member": "222222",
        "offers": 1,
        "categories": 0,
        "total": 50,
        "favorites": 5
    }
]


let result = data.reduce((a, b) => {
  a[b.member] = a[b.member] || {member : b.member};
  for(let property of Object.keys(b)){
    if(property == 'member') continue;
    a[b.member][property] = a[b.member][property] || 0;
    a[b.member][property] += b[property];
  }
  return a;
}, {});

result = Object.keys(result).map(e => result[e]);

console.log(result);

答案 1 :(得分:2)

另一个例子只有一个reduce和indexOf



const data =  [
    {
        "member": "111111",
        "offers": 0,
        "categories": 0,
        "total": 100,
        "favorites": 0
    },
    {
        "member": "111111",
        "offers": 2,
        "categories": 1,
        "total": 400,
        "favorites": 1
    },
    {
        "member": "222222",
        "offers": 1,
        "categories": 0,
        "total": 50,
        "favorites": 5
    }
]

const merge = (target, props) => {
  for(p in props){
    if(p !== 'member') {
      target[p] += props[p]
    }
  }
  return target
}

const a = data.reduce((res, d) => {
  const idx = res.findIndex(r => r.member === d.member)
  if (idx >= 0) {
    const newRes = merge(res[idx], {...d})
    res.splice(res[idx], 1, newRes)
  } else {
    res.push(d)
  }
  return res
}, [])

console.log(a)