如何在对象数组上使用javascript reduce [重复]

问题描述 投票:2回答:8

我有一个对象数组,其中每个对象都有一个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))。
javascript
8个回答
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));

1
投票

我不知道,也许这个?:

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

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);

0
投票

你根本不需要reduce - 一个简单的for循环完成这项工作:

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"
  }
]

array.forEach(i => {
  let found = false
  array.forEach(j => {
    if (j == i) {
      found++;
    }
  });
  if (found) {
    array.forEach((k, l) => {
      if (k == i) {
        array.splice(l, 1);
        l--;
      }
    });
  }
});

console.log(array);

0
投票

您可以使用Map并且如果存在,则将mapeed数组设置为零长度。最后concat所有数组。

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);

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)


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)

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);
© www.soinside.com 2019 - 2024. All rights reserved.