JavaScript篇:数组找不同:如何快速找出两个数组间的'单身狗'元素?

大家好,我是江城开朗的豌豆,一名拥有6年以上前端开发经验的工程师。我精通HTML、CSS、JavaScript等基础前端技术,并深入掌握Vue、React、Uniapp、Flutter等主流框架,能够高效解决各类前端开发问题。在我的技术栈中,除了常见的前端开发技术,我还擅长3D开发,熟练使用Three.js进行3D图形绘制,并在虚拟现实与数字孪生技术上积累了丰富的经验,特别是在虚幻引擎开发方面,有着深入的理解和实践。

我一直认为技术的不断探索和实践是进步的源泉,近年来,我深入研究大数据算法的应用与发展,尤其在数据可视化和交互体验方面,取得了显著的成果。我也注重与团队的合作,能够有效地推动项目的进展和优化开发流程。现在,我担任全栈工程师,拥有CSDN博客专家认证及阿里云专家博主称号,希望通过分享我的技术心得与经验,帮助更多人提升自己的技术水平,成为更优秀的开发者。

大家好,我是前端工程师小杨。今天在工作中遇到了一个有趣的问题:如何快速找出两个数组中"独一无二"的元素?就像在一群情侣中找出单身狗一样,我们需要找出那些只在A数组或只在B数组中出现的数字。下面我就来分享几种实用的解决方法。

问题描述

假设我们有两个数组:

javascript 复制代码
var A = [1, 5, 6];
var B = [2, 6, 7];

我们需要找出:

  1. 只在A中出现的数字:[1, 5]
  2. 只在B中出现的数字:[2, 7]

方法一:使用filter和includes(ES6基础版)

javascript 复制代码
function findUniqueElements(arr1, arr2) {
  // 找出arr1中有而arr2中没有的元素
  const onlyInArr1 = arr1.filter(item => !arr2.includes(item));
  
  // 找出arr2中有而arr1中没有的元素
  const onlyInArr2 = arr2.filter(item => !arr1.includes(item));
  
  return {
    onlyInArr1,
    onlyInArr2
  };
}

// 使用示例
const result = findUniqueElements(A, B);
console.log('只在A中的元素:', result.onlyInArr1); // [1, 5]
console.log('只在B中的元素:', result.onlyInArr2); // [2, 7]

优点

  • 代码简洁易懂
  • 不需要额外库

缺点

  • 时间复杂度是O(n²),对于大数组性能较差

方法二:使用Set提高性能(ES6进阶版)

javascript 复制代码
function findUniqueElementsWithSet(arr1, arr2) {
  const set1 = new Set(arr1);
  const set2 = new Set(arr2);
  
  // 找出arr1中有而arr2中没有的元素
  const onlyInArr1 = [...set1].filter(item => !set2.has(item));
  
  // 找出arr2中有而arr1中没有的元素
  const onlyInArr2 = [...set2].filter(item => !set1.has(item));
  
  return {
    onlyInArr1,
    onlyInArr2
  };
}

优点

  • 使用Set去重并提高查找速度
  • Set的has方法时间复杂度是O(1),整体性能提升到O(n)

缺点

  • 需要先将数组转为Set

方法三:一行代码解决方案(炫技版)

如果你喜欢简洁的代码,可以用这个:

javascript

复制

下载

css 复制代码
const findUnique = (a, b) => [  a.filter(item => !b.includes(item)),  b.filter(item => !a.includes(item))];

const [onlyInA, onlyInB] = findUnique(A, B);

实际应用场景

最近我在开发一个用户权限管理系统时就用到了这个方法:

javascript 复制代码
// 旧的权限列表
const oldPermissions = ['read', 'write', 'delete'];

// 新的权限列表
const newPermissions = ['read', 'write', 'share'];

// 找出新增和删除的权限
const [removedPermissions, addedPermissions] = findUnique(oldPermissions, newPermissions);

console.log('需要删除的权限:', removedPermissions); // ['delete']
console.log('需要添加的权限:', addedPermissions); // ['share']

这样就能快速知道权限变化,方便进行后续操作。

性能对比

为了让大家更直观地了解不同方法的性能差异,我做了个简单测试:

javascript 复制代码
// 生成两个包含10000个随机数的数组
const bigArr1 = Array.from({length: 10000}, () => Math.floor(Math.random() * 100000));
const bigArr2 = Array.from({length: 10000}, () => Math.floor(Math.random() * 100000));

console.time('filter方法');
findUniqueElements(bigArr1, bigArr2);
console.timeEnd('filter方法');

console.time('Set方法');
findUniqueElementsWithSet(bigArr1, bigArr2);
console.timeEnd('Set方法');

在我的电脑上测试结果:

  • filter方法:约200ms
  • Set方法:约10ms

可见在大数据量时,Set方法的优势非常明显!

注意事项

  1. 数组元素类型:上述方法适用于基本类型,如果是对象数组需要特殊处理
  2. NaN处理:Set和includes对NaN的处理有差异,需要注意
  3. 去重:如果原数组可能有重复元素,建议先用Set去重

总结

找出两个数组间的差异是前端开发中的常见需求,今天介绍了三种方法:

  1. 基础filter法:适合小数组,代码简单
  2. 高性能Set法:适合大数据量,推荐使用
  3. 炫技单行法:适合简单场景,装X必备

记住,没有最好的方法,只有最适合当前场景的方法。希望这篇文章能帮你下次遇到类似问题时快速解决!

如果你有更好的方法或者有趣的实现思路,欢迎在评论区分享交流~

相关推荐
风继续吹..1 小时前
后台管理系统权限管理:前端实现详解
前端·vue
yuanmenglxb20041 小时前
前端工程化包管理器:从npm基础到nvm多版本管理实战
前端·前端工程化
新手小新2 小时前
C++游戏开发(2)
开发语言·前端·c++
我不吃饼干2 小时前
【TypeScript】三分钟让 Trae、Cursor 用上你自己的 MCP
前端·typescript·trae
小杨同学yx3 小时前
前端三剑客之Css---day3
前端·css
星月心城4 小时前
Promise之什么是promise?(01)
javascript
二川bro4 小时前
第二篇:Three.js核心三要素:场景、相机、渲染器
开发语言·javascript·数码相机
Mintopia5 小时前
🧱 用三维点亮前端宇宙:构建你自己的 Three.js 组件库
前端·javascript·three.js
故事与九5 小时前
vue3使用vue-pdf-embed实现前端PDF在线预览
前端·vue.js·pdf
小西↬5 小时前
vite+vue3+websocket处理音频流发送到后端
javascript·websocket·音视频