JS小技巧,如何去重对象数组?

本文介绍了在JavaScript中针对对象数组去重的多种方法,包括filter+findIndex、reduce、forEach+some、Map、Object.create以及结合For...of和find处理多属性去重。这些方法适用于不同场景,根据项目需求选择合适的方法。

关于数组对象去重的业务场景,想必大家都遇到过类似的需求吧,这对这样的需求你是怎么做的呢。下面我就先和大家分享下如果是基于对象的1个属性是怎么去重实现的。

方法一:使用 .filter() 和 .findIndex() 相结合的方法

使用 Array.prototype.filter() 和 Array.prototype.findIndex():使用 filter() 方法过滤掉重复的元素,使用 findIndex() 方法判断对象是否重复,代码如下:

const arr = [{id: 1, name: "a"}, {id: 2, name: "b"}, 
             {id: 1, name: "c"}, {id: 3, name: "d"}];
const uniqueArr = arr.filter((item, index) => 
     arr.findIndex(i => i.id === item.id) === index);

方法二:使用 .reduce() 方法

使用 reduce() 方法维护一个累加器,通过对象的属性来判断是否重复,代码如下:

const arr = [{id: 1, name: "a"}, {id: 2, name: "b"},
             {id: 1, name: "c"}, {id: 3, name: "d"}];
const uniqueArr = arr.reduce((acc, curr) => {
  if (!acc.find(item => item.id === curr.id)) {
    acc.push(curr);
  }
  return acc;
}, []);

方法三、使用 .forEach() 和 .some() 相结合的方法

使用 forEach() 方法遍历数组,使用 some() 方法判断是否重复,代码如下:

const arr = [{id: 1, name: "a"}, {id: 2, name: "b"}, 
             {id: 1, name: "c"}, {id: 3, name: "d"}];
const uniqueArr = [];
arr.forEach(item => {
  if (!uniqueArr.some(i => i.id === item.id)) {
    uniqueArr.push(item);
  }
});

方法四:使用 Map

使用 Map 结构去重对象数组时,需要借助 array.map() 函数将对象数组进行转换,示例代码如下:

const arr = [{id: 1, name: "a"}, {id: 2, name: "b"}, 
             {id: 1, name: "c"}, {id: 3, name: "d"}];
const uniqueArr = [...new Map(arr.map(item => [item.id, item])).values()];

方法五: Object.create()

使用Object.create(),按照对象的属性来判断是否重复,代码如下:

const arr = [{id: 1, name: "a"}, {id: 2, name: "b"}, 
             {id: 1, name: "c"}, {id: 3, name: "d"}];
const uniqueArr = arr.filter(function (item) {
    return !this[item.id] && (this[item.id] = true);
}, Object.create(null));

方法六: For const of 和 find 结合

  • 这个方法的思想与方法3类似 ,其思路结构如下:
  • 创建一个空的唯一数组来存储唯一对象。
  • 循环遍历数组中的对象。对于每个对象,如果它不是重复的,则将其添加到唯一数组。否则,忽略它
const arr = [{id: 1, name: "a"}, {id: 2, name: "b"}, 
  {id: 1, name: "c"}, {id: 3, name: "d"}];
const unique = [];
for (const item of arr) {
  const isDuplicate = unique.find((obj) => obj.id === item.id);
  if (!isDuplicate) {
    unique.push(item);
  }
}

针对多个属性进行去重

有时候,您可能希望仅当对象具有两个或多个具有相同值的属性时才将其视为重复对象——多个属性值相同。

对于这种情况,我们可以将上述方法进行稍微调整就可以进行使用,有部分方法可能不适用,有哪些不合适,这个问题留给大家,欢迎大家在评论区补充。

我们拿使用 .filter() 和 .findIndex() 相结合的方法尝试下,看看如何操作:

const arr = [{id: 1, name: "a"}, {id: 2, name: "b"}, 
             {id: 1, name: "a"}, {id: 3, name: "d"}];
const uniqueArr = arr.filter((item, index) => 
                             arr.findIndex(i => i.id === item.id 
                                && i.name === item.name) === index);

我们再使用 For const of 和 find 结合的方法,也能实现同样的效果

const arr = [{id: 1, name: "a"}, {id: 2, name: "b"}, 
  {id: 1, name: "a"}, {id: 3, name: "d"}];
const unique = [];
for (const item of arr) {
  const isDuplicate = unique.find((obj) =>
    obj.id === item.id && obj.name ==item.name);
  if (!isDuplicate) {
    unique.push(item);
  }
}
console.log(unique)

结束

其他几个方法的改造,欢迎大家作为练习进行尝试,这里就不在一一举例了,今天的分享就到这里,今天分享的这些方法都可以实现对象数组的去重,具体使用哪种方法取决于个人的喜好和项目的需求。

### 数组的常见方法 #### 方法一:使用 ES6 的 `Set` 结构 通过将数组转换为 `Set` 对象,再将其转回数组的形式完成操作。这是目前最简洁、高效的一种方式。 ```javascript const arr = [1, 2, 2, 3, 3, 4, 5, 5]; const newArr = Array.from(new Set(arr)); console.log(newArr); // 输出: [1, 2, 3, 4, 5] ``` 这种方法利用了 `Set` 数据结构不允许存在复值的特点[^2]。 --- #### 方法二:使用扩展运算符 (`...`) 和 `Set` 这种方式是对第一种方法的简化版本,同样基于 `Set` 的特性实现。 ```javascript const arr = [1, 9, 8, 8, 7, 2, 5, 3, 3, 3, 2, 3, 1, 4, 5, 444, 55, 22]; const newArr = [...new Set(arr)]; console.log(newArr); // 输出: [1, 9, 8, 7, 2, 5, 3, 4, 444, 55, 22] ``` 此方法更加直观易读,适合现代浏览器环境下的开发需求[^4]。 --- #### 方法三:使用 `filter()` 配合 `indexOf()` 该方法的核心在于遍历原数组中的每一项,并判断当前项在其整个数组范围内的首次索引位置是否等于其当前位置。如果相等,则保留;否则剔除。 ```javascript function removeDuplicates(arr) { return arr.filter((item, index) => arr.indexOf(item) === index); } const arr = [1, 2, 2, 3, 3, 4, 5, 5]; console.log(removeDuplicates(arr)); // 输出: [1, 2, 3, 4, 5] ``` 这种技术虽然稍显复杂一些,但在兼容性较差的老环境中仍然非常有效。 --- #### 方法四:双循环手动比较 这是一种较为原始但也十分可靠的技术手段——即逐一遍历目标列表里的每一个成员并与之前已处理过的部分做逐一对照检测是否存在相同者。一旦发现匹配则跳过记录过程继续前进直到结束为止。 ```javascript function unique(array){ let result=[]; for(let i=0;i<array.length;i++){ if(result.indexOf(array[i])===-1){ result.push(array[i]); } } return result; } var array=[1,"a",2,"b","c",1,"d"]; document.write(unique(array));//输出:[1,"a",2,"b","c","d"] ``` 尽管效率较低,但它无需依赖任何高级功能即可达成目的,在某些特定场景下可能成为首选方案之一[^3]。 --- #### 方法五:对象键值法(适用于简单类型的数组) 创建一个临时的对象字典用于存储已经遇到的数据作为属性名标记下来;当再次碰到相同的数值时因为同名属性无法被新定义而自然忽略掉它从而达到过滤效果的目的。 ```javascript function deduplicate(arr){ var obj={}; var res=[]; for(var i=0; i<arr.length; ++i){ if(!obj[arr[i]]){ res.push(arr[i]); obj[arr[i]]=true; } } return res; } deduplicate([1,'a',2,'b','c',1,'d']);//[1,"a",2,"b","c","d"] ``` 对于只含有基本数据类型元素的小规模集合来说这是一个不错的选择[^3]。 --- 以上就是几种主流且常用的JavaScript数组技巧介绍及其具体应用实例展示说明文档内容摘录整理而成的结果呈现形式而已啦!
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值