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

  • 时间:2021-03-20 19:23 作者:alanwhy 来源: 阅读:573
  • 扫一扫,手机访问
摘要:我们之前看过了 手写数组去重、扁平化函数 ,以及 不产生新数组,删除数组里的重复元素 ,这里再次加深一下,假如是数组元素包含对象等类型,又该如何去重喃?示例如下:如传入的数组元素为 [123, ”meili”, ”123”, ”mogu”, 123] ,则输出: [123, ”meili”, ”12

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

示例如下:

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

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

  • 全部评论(0)
最新发布的资讯信息
【系统环境|】技术JD解码黑箱:CTO埋的隐藏关卡与破局指南(2026-01-08 23:14)
【系统环境|】K8S部署 Qwen3-32B 大模型详细教程(2026-01-08 23:13)
【系统环境|】VibeCoding终极指南:别做Prompt做PM(2026-01-08 23:13)
【系统环境|】工具参数预设功能实现与安全实践指南:基于LlamaIndex Forge(2026-01-08 23:13)
【系统环境|】Spring AI + OpenAI 环境构建完整指南(2026-01-08 23:13)
【系统环境|】FFT魔力觉醒:FFTW C++高性能变换指南(2026-01-08 23:13)
【系统环境|】Docker+Ollama+Deepseek 本地大模型部署指南(2026-01-08 23:13)
【系统环境|】「WordPress建站05」宝塔安装网站SSL、伪静态设置(2026-01-08 23:12)
【系统环境|】域名还有更便宜的?从namesilo迁移到cloudflare,详细教程!(2026-01-08 23:12)
【系统环境|】Eplan P8 win10系统安装方法,亲测可用(2026-01-08 23:12)
手机二维码手机访问领取大礼包
返回顶部