TypeScript: 判断两个数组的内容是否相等

一、直接遍历

ts 复制代码
// 1.直接遍历
const arr1: any[] = ["apple", "banana", NaN];
const arr2: any[] = ["apple", NaN, "banana"];

function fn1(arr1: any[], arr2: any[]) {
  // Array.some(): 有一项不满足,返回false
  if (arr1.length !== arr2.length) {
    return false;
  }
  return arr1.some((item: any) => arr2.indexOf(item) === -1) ? false : true;
//   return !arr1.some((item) => !arr2.includes(item));
}
console.log("直接遍历 => ", fn1(arr1, arr2)); // false

NaN 会有问题

优化版本

ts 复制代码
// 1.直接遍历
const arr1: any[] = ["apple", "banana", NaN];
const arr2: any[] = ["apple", NaN, "banana"];

function fn1(arr1: any[], arr2: any[]) {
  // Array.some(): 有一项不满足,返回false
  if (arr1.length !== arr2.length) {
    return false;
  }
//   return arr1.some((item: any) => arr2.indexOf(item) === -1) ? false : true;
  return !arr1.some((item) => !arr2.includes(item));
}
console.log("直接遍历 => ", fn1(arr1, arr2)); // true

Array.prototype.indexOf() 是使用的严格相等算法 => NaN值永远不相等

Array.prototype.includes() 是使用的零值相等算法 => NaN值视作相等

二、把重复元素编号

ts 复制代码
// 2.把重复元素标识编号
function fn3(arr1: any[], arr2: any[]) {
  if (arr1.length !== arr2.length) {
    return false;
  }
  // 重复数组元素 加1、2、3
  const countArr1 = updateArray(arr1);
  const countArr2 = updateArray(arr2);

  // arr 数组 元素重复转换成 val1,val2
  function updateArray(arr: any[]) {
    const countMap: Map<any, number> = new Map();
    const updateArr: any[] = [];
    for (const ele of arr) {
      //   const cnt = !countMap.has(ele) ? 1 : countMap.get(ele)! + 1;
      const cnt = (countMap.get(ele) || 0) + 1;
      countMap.set(ele, cnt);
      updateArr.push(`${ele}${cnt}`); // 有问题
      // 等同于
      //   if (!countMap.has(ele)) {
      //     // 如果元素是第一次出现,直接添加到结果数组
      //     countMap.set(ele, 0)
      //     updateArr.push(ele)
      //   } else {
      //     // 如果元素已经出现过,添加带有编号的新元素到结果数组
      //     const count = countMap.get(ele)! + 1
      //     countMap.set(ele, count)
      //     updateArr.push(`${ele}${count}`)
      //   }
    }
    return updateArr;
  }
  // console.log("countArr1 => ", countArr1);
  // console.log("countArr2 => ", countArr2)
  return !countArr1.some((item) => !countArr2.includes(item));
}

const array1 = ["apple", "banana", "cherry", "banana"];
const array2 = ["banana", "apple", "banana", "cherry"];
console.log("把重复元素标识编号 => ", fn3(array1, array2)); // true

// 其实这种存在漏洞的
const array3 = ["apple", "banana", "cherry", "banana", 1, "1", "1"];
const array4 = ["banana", "apple", "banana", "cherry", "1", 1, 1];
// 应该是false
console.log("把重复元素标识编号 存在漏洞 => ", fn3(array3, array4)); // true

三、统计元素次数

ts 复制代码
// 3.统计元素次数
function fn4(arr1: any[], arr2: any[]) {
  if (arr1.length !== arr2.length) {
    return false;
  }
  // 创建计数对象,用于记录每个元素在数组中的出现次数
  const countMap1: Map<any, number> = count(arr1);
  const countMap2: Map<any, number> = count(arr2);

  function count(arr: any[] = []) {
    const map: Map<any, number> = new Map();
    for (const item of arr) {
      map.set(item, (map.get(item) || 0) + 1);
    }
    return map;
  }

  //检查计数对象是否相等

//   console.log("countMap1 => ", countMap1)
//   console.log("countMap2 => ", countMap2)
  for (const [key, count] of countMap1) {
    if (countMap2.get(key) !== count) {
        return false;
    }
  }
  return true;
}

const array5 = ["apple", "banana", "cherry", "banana", 1, "1", "11", 11];
const array6 = ["banana", "apple", "banana", "cherry", "1", 1, "11", 11];

console.log("统计元素次数 => ", fn4(array5, array6)); // true
console.log("统计元素次数 => ", fn4(array3, array4)); // false

四、+1,-1

ts 复制代码
// 4.+1,-1
function fn5(arr1: any[], arr2: any[]) {
    if (arr1.length !== arr2.length) {
        return false;
    }
    const countMap: Map<any, number> = new Map();

    // 计算第一个数组的元素
    for (const item of arr1) {
        countMap.set(item, (countMap.get(item) || 0) + 1);
    }

    // 比较第二个数组
    for (const item of arr2) {
        const val = countMap.get(item)
        if (val === undefined || val <= 0) {
            return false;
        }
        countMap.set(item, val - 1)
    }
    return true;
}
console.log("+1, -1 => ", fn5(array3, array4)) // false
console.log("+1, -1 => ", fn5(array5, array6))  // true

总结

  • 先判断长度,长度不等,必然不等
  • 元素可重复
  • 边界情况考虑
    • '1' 和 1 (Object的key是字符串,Map的key没有限制)
    • NaN
    • null、undefined

相关知识

JS规范中的相等、严格相等、零值相等以及同值相等
  • 非严格相等比较:==
  • 严格相等比较:===(用于Array.prototype.indexOf(),Array.prototype.lastIndexOf(),case-matching)
  • 零值相等:用于%TypeArray%和ArrayBuffer构造函数、Map和Set操作、String.prototype.inclues()
  • 同值相等:用于所有其他地方

零值相等:与同值相等类似,不过+0 与-0 相等
同值相等:确定两个值是否在任何情况次啊功能上是相同的

相关推荐
恋猫de小郭14 分钟前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60617 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅8 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端