实现一个数组(包含对象等类型元素)去重函数

作者 : 开心源码 本文共2777个字,预计阅读时间需要7分钟 发布时间: 2022-05-14 共263人阅读

我们之前看过了 手写数组去重、扁平化函数 ,以及 不产生新数组,删除数组里的重复元素 ,这里再次加深一下,假如是数组元素包含对象等类型,又该如何去重喃?

示例如下:

  1. 如传入的数组元素为 [123, "meili", "123", "mogu", 123] ,则输出: [123, "meili", "123", "mogu"]
  2. 如传入的数组元素为 [123, [1, 2, 3], [1, "2", 3], [1, 2, 3], "meili"] ,则输出: [123, [1, 2, 3], [1, "2", 3], "meili"]
  3. 如传入的数组元素为 [123, {a: 1}, {a: {b: 1}}, {a: "1"}, {a: {b: 1}}, "meili"] ,则输出: [123, {a: 1}, {a: {b: 1}}, {a: "1"}, "meili"]

基础:JSON.stringify 去重

const removeDuplicates = (arr) => {  let map = new Map();  arr.forEach((item) => {    map.set(JSON.stringify(item), item);  });  return [...map.values()];};// 测试removeDuplicates([123, "meili", "123", "mogu", 123]);// [123, "meili", "123", "mogu"]removeDuplicates([123, [1, 2, 3], [1, "2", 3], [1, 2, 3], "meili"]);// [123, [1, 2, 3], [1, "2", 3], "meili"]removeDuplicates([  123,  { a: 1 },  { a: { b: 1 } },  { a: "1" },  { a: { b: 1 } },  "meili",]);// [123, {a: 1}, a: {b: 1}, {a: "1"}, "meili"]

深入一下

使用 JSON.stringify ,假如数组元素是 object 类型且里面键的顺序不同则会认为是两个不同放入数组元素

let o1 = { a: 1, b: 2 };let o2 = { b: 2, a: 1 };JSON.stringify(o1);// "{"a":1,"b":2}"JSON.stringify(o2);// "{"b":2,"a":1}"JSON.stringify(o1) === JSON.stringify(o2);// false

处理思路:

一个数组(包含对象等类型元素)去重函数,需要在基础类型判断相等条件下满足以下条件:

  • 假如元素是数组类型,则需要数组中的每一项相等
  • 假如元素是对象类型,则需要对象中的每个键值对相等

去重本身就是遍历数组,而后比较数组中的每一项能否相等而已,所以关键步骤有两步:比较去重

比较:

  • 首先判断类型能否一致,类型不一致则返回认为两个数组元素是不同的,否则继续
  • 假如是数组类型,则递归比较数组中的每个元素能否相等
  • 假如是对象类型,则递归比较对象中的每个键值对能否相等
  • 否则,直接 === 比较

去重:

  • 采用 reduce 去重,初始 accumulator[]
  • 采用 findIndex 找到 accumulator 能否包含相同元素,假如不包含则加入,否则不加入
  • 返回最终的 accumulator ,则为去重后的数组

代码实现:

// 获取类型const getType = (function () {  const class2type = {    "[object Boolean]": "boolean",    "[object Number]": "number",    "[object String]": "string",    "[object Function]": "function",    "[object Array]": "array",    "[object Date]": "date",    "[object RegExp]": "regexp",    "[object Object]": "object",    "[object Error]": "error",    "[object Symbol]": "symbol",  };  return function getType(obj) {    if (obj == null) {      return obj + "";    }    // javascript高级程序设计中提供了一种方法,可以通用的来判断原始数据类型和引用数据类型    const str = Object.prototype.toString.call(obj);    return typeof obj === "object" || typeof obj === "function"      ? class2type[str] || "object"      : typeof obj;  };})();/** * 判断两个元素能否相等 * @param {any} o1 比较元素 * @param {any} o2 其余元素 * @returns {Boolean} 能否相等 */const isEqual = (o1, o2) => {  const t1 = getType(o1);  const t2 = getType(o2);  // 比较类型能否一致  if (t1 !== t2) return false;  // 类型一致  if (t1 === "array") {    // 首先判断数组包含元素个数能否相等    if (o1.length !== o2.length) return false;    // 比较两个数组中的每个元素    return o1.every((item, i) => {      // return item === target      return isEqual(item, o2[i]);    });  }  if (t2 === "object") {    // object类型比较相似数组    const keysArr = Object.keys(o1);    if (keysArr.length !== Object.keys(o2).length) return false;    // 比较每一个元素    return keysArr.every((k) => {      return isEqual(o1[k], o2[k]);    });  }  return o1 === o2;};// 数组去重const removeDuplicates = (arr) => {  return arr.reduce((accumulator, current) => {    const hasIndex = accumulator.findIndex((item) => isEqual(current, item));    if (hasIndex === -1) {      accumulator.push(current);    }    return accumulator;  }, []);};// 测试removeDuplicates([  123,  { a: 1 },  { a: { b: 1 } },  { a: "1" },  { a: { b: 1 } },  "meili",  { a: 1, b: 2 },  { b: 2, a: 1 },]);// [123, {a: 1}, a: {b: 1}, {a: "1"}, "meili", {a: 1, b: 2}]

原文链接:实现一个数组(包含对象等类型元素)去重函数

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 实现一个数组(包含对象等类型元素)去重函数

发表回复