挑战1000道javascript手写题之数组去重进阶版(2)

引用类型数组去重

上一篇文章中我们探讨了使用javascript对只包含原始类型元素的数组进行去重,遗留下一个问题,就是当数组中包含两个“长得一样”的对象的时候,该如何去重?

测试数据

let a = {"a": 1};
let b = {"a": 1};
let c = {"b": 2};
let arr = [a, b, c];

使用set去重是失效的

console.log([...new Set(arr)]); // [ { a: 1 }, { a: 1 }, { b: 2 } ]

实现过程

需要先实现一个判断两个对象是否“长得一样”的函数。

/**
 * @description: 检查两个对象 obj1 和 obj2 是否值相等
 * @param {*} obj1
 * @param {*} obj2
 * @return {*}
 */
function checkObj(obj1, obj2) {
  // 指向同一内存
  if (obj1 === obj2) return true;
  let arr1 = Object.keys(obj1),
    arr2 = Object.keys(obj2);
  // 判断属性值是否相等
  if (arr1.length != arr2.length) return false;
  for (const k in arr1) {
    if (typeof arr1[k] == "object" || typeof arr2[k] == "object") {
      if (!checkObj(arr1[k], arr2[k])) return false;
    } else if (arr1[k] !== arr2[k]) {
      return false;
    }
  }
  return true;
}

在数组原型扩展includesObj 方法,判断数组上是否存在某对象。

/**
 * @description: 在数组原型上写方法
 * @param {*} itemObj
 * @return {*}
 */
Array.prototype.includesObj = function (itemObj) {
  let flag = false;
  for (let i = 0; i < this.length; i++) {
    if (checkObj(this[i], itemObj)) {
      flag = true;
      break;
    }
  }
  return flag;
};

实现去重函数,遍历输入的数组 nums,对于每个对象,使用 includesObj 方法检查它是否已经存在于 result 中。如果当前对象不在 result 中,则将其添加到 result 中。最终返回 result 数组,即为去重后的对象数组。

/**
 * @description: 针对对象数组,且可能出现对象引用的问题
 * @param {*} arr
 * @return {*}
 */
function uniqSpecial(arr) {
  const result = [];
  for (let i = 0; i < arr.length; i++) {
    // 如果不存在
    if (!result.includesObj(arr[i])) result.push(arr[i]);
  }
  return result;
}

结果测试

console.log(uniqSpecial(arr)); // [ { a: 1 }, { b: 2 } ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端之仙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值