从对象数组中删除元素

时间:2018-02-08 06:45:47

标签: javascript ecmascript-6

基本上我想对具有相同key值的对象进行分组。

const dupObj = [
  {
    "uuid": "",
    "quantity": 0,
    "distributeStoreUuid": "",
    "distributeStore__acceptanceTaskDetailsUuid": "",
    "acceptanceTaskUuid": "acabb997-fc06-47ba-ae29-d7aea9a6a022",
  },
  {
    "uuid": "",
    "quantity": 3,
    "acceptanceTaskUuid": "acabb997-fc06-47ba-ae29-d7aea9a6a022",
  }
 ]

这是预期的结果

[
 {
   "uuid": "",
   "quantity": 3,
   "distributeStoreUuid": "",
   "distributeStore__acceptanceTaskDetailsUuid": "",
   "acceptanceTaskUuid": "acabb997-fc06-47ba-ae29-d7aea9a6a022",
 }
]

我正在尝试使用ES6 Set,这是我到目前为止所做的

const uniKeys = [...(new Set(dupObj.map(({ acceptanceTaskUuid }) => acceptanceTaskUuid)))];

有什么想法吗?提前致谢

5 个答案:

答案 0 :(得分:2)

以下代码应该有效:



const dedupe = originalArray => originalArray.reduce((array, obj) => {
  const index = array.findIndex(item => item.acceptanceTaskUuid === obj.acceptanceTaskUuid)
    
  // if there already is no other acceptance task uuid
  // then append the obj to the array else add the quantities together
  return index === -1 ? [...array, obj] : Object.assign([], array, {
    [index]: Object.assign({}, array[index], obj)
  })
}, [])

console.log(dedupe([
  {
    "uuid": "",
    "quantity": 0,
    "distributeStoreUuid": "",
    "distributeStore__acceptanceTaskDetailsUuid": "",
    "acceptanceTaskUuid": "acabb997-fc06-47ba-ae29-d7aea9a6a022",
  },
  {
    "uuid": "",
    "quantity": 3,
    "acceptanceTaskUuid": "acabb997-fc06-47ba-ae29-d7aea9a6a022",
  },
  {
    "uuid": "",
    "quantity": 4,
    "acceptanceTaskUuid": "foobar"
  },
  {
    "uuid": "",
    "quantity": 13,
    "acceptanceTaskUuid": "foobarbaz",
  },
  {
    "uuid": "",
    "quantity": 6,
    "acceptanceTaskUuid": "foobar",
  },
]))




findIndex函数返回数组中与条件匹配的第一项的索引。基本上上面的代码以一个空数组开始,循环遍历原始数组(reduce)并找到具有与每次迭代的当前对象相同的接受任务uuid​​的项的索引。如果有重复,那么它会将数量加在一起,否则它只是将新项目附加到数组

编辑:制作不可变的

答案 1 :(得分:1)

您可以将reduce数组转换为Map。在每次传递中,从Map获取具有相同acceptanceTaskUuid的对象,或使用空对象,将其分配给current。使用forEach迭代数组的对象(o)条目,并检查该属性是否为current中的数字,然后添加,或者如果没有则分配。然后spread Map值得到一个数组:

const dupObj = [{"uuid":"","quantity":1,"distributeStoreUuid":"","distributeStore__acceptanceTaskDetailsUuid":"","acceptanceTaskUuid":"acabb997-fc06-47ba-ae29-d7aea9a6a022"},{"uuid":"","quantity":3,"acceptanceTaskUuid":"acabb997-fc06-47ba-ae29-d7aea9a6a022"}]

const uniques = [...dupObj.reduce((m, o) => {
  const current = m.get(o.acceptanceTaskUuid) || {}

  Object.entries(o).forEach(([key, value]) => 
    current[key] = typeof current[key] === 'number' ? current[key] + value : value)

  return m.set(o.acceptanceTaskUuid, current)
}, new Map()).values()]

console.log(uniques)

答案 2 :(得分:0)

您可以使用array#reduce并在acceptanceTaskUuid键上存储对象,如果出现重复的对象,请使用Object.assign合并它们。然后使用Object.values()提取值。

const dupObj = [ { "uuid": "", "quantity": 0, "distributeStoreUuid": "", "distributeStore__acceptanceTaskDetailsUuid": "", "acceptanceTaskUuid": "acabb997-fc06-47ba-ae29-d7aea9a6a022", }, { "uuid": "", "quantity": 3, "acceptanceTaskUuid": "acabb997-fc06-47ba-ae29-d7aea9a6a022"} ],
      result = Object.values(dupObj.reduce((r, o) => {
        r[o.acceptanceTaskUuid] = Object.assign(r[o.acceptanceTaskUuid] || {}, o);
        return r;
      }, {}));
console.log(result);

答案 3 :(得分:0)

您可以使用一个Map(或普通的JS对象),其中键是您的id并对该对象赋值,然后使用Object.assign()将重复的对象合并在一起。

这是一个简单的循环算法,没有任何花哨的缩减或映射操作,应该很容易理解。

let map = new Map();
for (let obj of dupObj) {
    if (map.has(obj.acceptanceTaskUuid))
        map.set(obj.acceptanceTaskUuid, Object.assign(map.get(obj.acceptanceTaskUuid), obj)); // merge
    else
        map.set(obj.acceptanceTaskUuid, obj);
}

// map.values() return an iterator, not an array
for (let obj of map.values()) {
    console.log(obj);
}

答案 4 :(得分:-2)

为什么不使用lodash,如此简单,如此简单。

https://lodash.com/docs/4.17.5#filter