如何在对象数组上使用javascript reduce

时间:2019-02-27 08:34:45

标签: javascript

我有一个对象数组,其中每个对象都有一个id键。 其中一些对象具有重复出现的ID,我想删除这些重复出现的对象。

例如:

let array = [{
    "id": "123",
    "country": "Brazil",
    "address": "xyz abc",
    "date": "Dec 17, 1995, 9:45:17 PM"
  },
  {
    "id": "443",
    "country": "Russia",
    "address": "qwd qwd qwdqw",
    "date": "Dec 17, 1965, 9:45:17 PM"
  },
  {
    "id": "123",
    "country": "Canada",
    "address": "ktktkt",
    "date": "Dec 17, 1925, 9:45:17 PM"
  },
.
.
.
{}]

在上面的数组中,因为索引0和索引2共享相同的id键值,所以我想将它们全部从数组中删除。

  • 我正在根据复杂度(仅线性(O(n)))寻找最佳代码。

8 个答案:

答案 0 :(得分:1)

我不知道,也许是这样吗?:

array.filter(function(d,i){return !this[d.id] && (this[d.id] = d.id)},{})

答案 1 :(得分:1)

由于要完全删除重复的值,因此可以尝试此操作。首先找到重复项,然后过滤原始数组。

let array = [{
    "id": "123",
    "country": "Brazil"
  },{
    "id": "443",
    "country": "Russia"
  },{
    "id": "123",
    "country": "Canada"
  },{
    "id": "123",
    "country": "Canada"
  },{
    "id": "345",
    "country": "UK"
  }];

const removeDups = (data) => {
	
	const dups = data.reduce((acc, { id }) => {
		acc[id] = (acc[id] || 0) + 1;
		return acc;
	}, {});

	return data.filter(({ id }) => dups[id] === 1);
}

console.log(removeDups(array));

答案 2 :(得分:1)

无需减少,只需排序和过滤即可:

let array = [{
    "id": "123",
    "country": "Brazil",
    "address": "xyz abc",
    "date": "Dec 17, 1995, 9:45:17 PM"
  },
  {
    "id": "443",
    "country": "Russia",
    "address": "qwd qwd qwdqw",
    "date": "Dec 17, 1965, 9:45:17 PM"
  },
  {
    "id": "123",
    "country": "Canada",
    "address": "ktktkt",
    "date": "Dec 17, 1925, 9:45:17 PM"
  },
  
]


const output = array.sort((a, b) => a.id - b.id).filter((item, index, sorted) => {
  const before = sorted[index - 1] || {}
  const after = sorted[index + 1] || {}

  return item.id !== after.id && item.id !== before.id
})

console.log(output);

答案 3 :(得分:0)

您根本不需要panda-一个简单的reduce循环就可以完成工作:

for

答案 4 :(得分:0)

一种解决方案是将输入array聚合到键/值映射,其中值是共享相同id的项的列表。然后,您可以通过Object.values()从此地图中提取一个数组,过滤包含多个项的值,然后将这些单个项映射到最终输出:

let array = [{
    "id": "123",
    "country": "Brazil",
    "address": "xyz abc",
    "date": "Dec 17, 1995, 9:45:17 PM"
  },
  {
    "id": "443",
    "country": "Russia",
    "address": "qwd qwd qwdqw",
    "date": "Dec 17, 1965, 9:45:17 PM"
  },
  {
    "id": "123",
    "country": "Canada",
    "address": "ktktkt",
    "date": "Dec 17, 1925, 9:45:17 PM"
  }
]

const result = Object.values(array.reduce((map, item) => {

    map[item.id] = (map[item.id] || []).concat([item]);

    return map;

  }, {}))
  .filter(item => item.length === 1)
  .map(([item]) => item)

console.log(result)

答案 5 :(得分:0)

您可以简单地初始化count对象并使用简单的forEach循环填充它,然后使用filter

let arr = [{ id: "123", country: "Brazil", address: "xyz abc", date: "Dec 17, 1995, 9:45:17 PM" }, { id: "443", country: "Russia", address: "qwd qwd qwdqw", date: "Dec 17, 1965, 9:45:17 PM" }, { id: "123", country: "Canada", address: "ktktkt", date: "Dec 17, 1925, 9:45:17 PM" }]

count = {}

arr.forEach(obj => {
  if (count[obj.id]) {
      count[obj.id] += 1
  } else {
      count[obj.id] = 1
  } 
})



console.log(arr.filter(obj => count[obj.id] === 1))

运行时间(代码复杂度):O(N)

答案 6 :(得分:0)

使用Array.reduce()通过ID构建中间字典,该字典的值均为具有该ID的所有项目。然后使用Object.values()枚举此字典的值,并使用Array.filter()过滤出包含多个元素的条目,然后使用Array.flat()展平结果:

const array = [{
    "id": "123",
    "country": "Brazil",
    "address": "xyz abc",
    "date": "Dec 17, 1995, 9:45:17 PM"
  },
  {
    "id": "443",
    "country": "Russia",
    "address": "qwd qwd qwdqw",
    "date": "Dec 17, 1965, 9:45:17 PM"
  },
  {
    "id": "123",
    "country": "Canada",
    "address": "ktktkt",
    "date": "Dec 17, 1925, 9:45:17 PM"
  },
];

const singles = Object.values(array.reduce((acc, x) => {
  acc[x.id] = [...(acc[x.id] || []), x];
  return acc;
}, {})).filter(x => x.length === 1).flat();

console.log(singles);

答案 7 :(得分:0)

您可以使用Map,如果存在,请将映射数组的长度设置为零。最后,连接所有数组。

var array = [{ id: "123", country: "Brazil", address: "xyz abc", date: "Dec 17, 1995, 9:45:17 PM" }, { id: "443", country: "Russia", address: "qwd qwd qwdqw", date: "Dec 17, 1965, 9:45:17 PM" }, { id: "123", country: "Canada", address: "ktktkt", date: "Dec 17, 1925, 9:45:17 PM" }],
    result = [].concat(...array.map((m => (o, i) => {
        var temp = [];
        if (m.has(o.id)) {
            m.get(o.id).length = 0;
        } else {
            m.set(o.id, temp = [o]);
        }
        return temp;
   })(new Map)))

console.log(result);