惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
宝玉的分享
宝玉的分享
酷 壳 – CoolShell
酷 壳 – CoolShell
T
The Exploit Database - CXSecurity.com
Help Net Security
Help Net Security
腾讯CDC
Project Zero
Project Zero
C
CXSECURITY Database RSS Feed - CXSecurity.com
IT之家
IT之家
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tailwind CSS Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
D
Darknet – Hacking Tools, Hacker News & Cyber Security
L
LINUX DO - 最新话题
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Threatpost
N
News | PayPal Newsroom
C
Cybersecurity and Infrastructure Security Agency CISA
Hacker News - Newest:
Hacker News - Newest: "LLM"
S
SegmentFault 最新的问题
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
P
Proofpoint News Feed
A
Arctic Wolf
B
Blog RSS Feed
Forbes - Security
Forbes - Security
P
Privacy & Cybersecurity Law Blog
Attack and Defense Labs
Attack and Defense Labs
V2EX - 技术
V2EX - 技术
P
Proofpoint News Feed
I
Intezer
Application and Cybersecurity Blog
Application and Cybersecurity Blog
阮一峰的网络日志
阮一峰的网络日志
aimingoo的专栏
aimingoo的专栏
T
Tenable Blog
MyScale Blog
MyScale Blog
U
Unit 42
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
WordPress大学
WordPress大学
W
WeLiveSecurity
D
DataBreaches.Net
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
G
GRAHAM CLULEY
有赞技术团队
有赞技术团队
Martin Fowler
Martin Fowler
罗磊的独立博客
The Last Watchdog
The Last Watchdog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
Vulnerabilities – Threatpost
美团技术团队
Microsoft Security Blog
Microsoft Security Blog

少数派

派早报:Google 发布 Fitbit Air 等 - 少数派 「新人报到」確認需求,再開始 - 少数派 从 SOLO 独立开发者社区,我看到了越来越多开发者开始做自己的产品 - 少数派 我怎么管理那些"不常做,但总会忘"的生活事项 - 少数派 人形机器人量产元年,数据才是具身智能的“生死线” - 少数派 BuhoLaunchpad 高度还原 Mac 启动台:开发历程与思考 - 少数派 五年陪伴依然不舍,DIY 换壳后让罗技 MX Master 3 继续服役 - 少数派 新玩意 240|少数派的编辑们最近买了啥? - 少数派 一日一技|为什么你应该关闭 iOS 的键盘声音 - 少数派 我做了个插件和 Skills,一键提取任何网站的设计规范 Design.md - 少数派 住在三四线城市的你,该开始录播客了 - 少数派 甘南秘境,大白高国 - 少数派 AI的审美:谁让把我变成川内倫子 - 少数派 返工怎能不烦恼,打工人片单总有一部是你的「嘴替」 - 少数派 为了让「上厕所」更健康,我做了一个小工具 - 少数派 AI + Skill,能够让生成的文章去除 AI 味吗? - 少数派 新玩意|韶音OpenDots ONE 耳夹式耳机 - 少数派 《美满》| 在每一个春天的晚上相爱(362) - 少数派 新玩意|优篮子 PS01 MagSnap 磁吸支架 - 少数派 自我整合手记 | 我开始早睡了:用稳定规则,为自由托底 - 少数派 用龙虾(OpenClaw)两个多月,我最深的12个体会 - 少数派 听歌时间到,12 张你可能错过的 2025 华语乐坛好专辑 - 少数派 承诺能追吗 - 少数派 macOS 26启动台没了? 我做了个不一样的App启动器 - Keboard - 少数派 《四海为家的人》| INTJ对话INTJ(361) - 少数派 你发过的那些黑历史,是时候一次清干净了 - 少数派 新玩意:安安静静玩,越玩越专注:计客密码机 - 少数派 iPad 用户首次体验 Android 平板:vivo Pad6 Pro - 少数派 数据逻辑强 - 少数派 极北行+ | 一路向北,探访日本至北之地 | 001 - 少数派 万字剖析:千问App深度体验报告(2026) - 少数派 在2026年,如何真正防止别人抄袭你的作品 - 少数派 怎么用 50 块搭个 AI 语音助手?我踩了 3 天坑 - 少数派 YeeroAI:让 AI 对话真正成为知识管理的一部分 - 少数派 爬泰山 - 少数派 「旅图显影」 App 更新:这次,我们补上了一点「手感」 - 少数派 假期出门太折磨?我的 23 条经验帮你规划惬意旅行 - 少数派 工作流会变吗 - 少数派 Claude Opus 4.6 怎么用最省钱?我测了 5 种方案 - 少数派 GPT Image 2 让图文并茂不再稀罕 - 少数派 用户侧出发——什么是AI,我要不要学习? - 少数派 找片、转存、整理、播放一条龙!让你的付费网盘值回票价 - 少数派 欢迎试用!日课一问2.0插件 - 少数派 自己做的MDeditor,原本想购买 Typora 试了两次支付不成功,干脆自己做一个 - 少数派 vibe coding了一个 3MB 的小工具,让 ~/Downloads 彻底告别混乱 - 少数派 因为受不了 Mac 的风扇策略,我做了一个风扇控制工具 - 少数派 别只怪模型 - 少数派 Warp 终端的 AI 功能怎么用?我测了一周的体验 - 少数派 AI 写代码老是出 bug?这 5 个配置我后悔没早知道 - 少数派 「新玩意」苹果出相机可能就这样:Sigma BF + 45mm F2.8 DG Contemporary - 少数派 一个面向2030年的AI操作系统是什么样子的:浅谈cola这款有灵魂的Agent - 少数派 别只看写代码 - 少数派 每天解决10个问题,还是一口气攻坚解决400个? - 少数派 AI 交易机器人怎么搭?我用 Claude 跑了一周实盘 - 少数派 Maptoposter Online:把你爱的城市画成艺术海报 - 少数派 Function Calling 怎么用?我测了 3 个模型发现差距真大 - 少数派 Legend Talk:我做了个 AI 圆桌,让 160 位思想家围着你的问题转 - 少数派 如何找到自己的蓝方?在小县城寻找压力测试 - 少数派 语音输入与软件接口|2026年聊AI时,我们都聊些什么(上) - 少数派 混动已经卖爆,纯电又来补刀——钛7闪充版简直“不讲武德” - 少数派 本月玩什么|朋友收藏、识质存在、沙罗周期 - 少数派 为什么要每天坚持输出? - 少数派 Claude API 挂了好几个小时,你的项目有备用方案吗? - 少数派 Function Calling 没你想的复杂——我用它做了个有点用的工具 - 少数派 登录系统立即播放视频或者图片音乐的软件 - 少数派 我为什么创建 FlipHTML5 下载工具 - 少数派 残局没电?多品牌外设电量统一管理软件EasyBluetooth已支持RTSS游戏内显示以及AIDA64 - 少数派 前往通义路的路 - 少数派 太好看了,媲美Sun的个人导航页,NAS部署星云门户 - 少数派 乌黑嘴唇“一键检测”上线了 - 少数派 派早报:Claude AI 接入多个创意软件生态、FILCO 生产方接手品牌等 - 少数派 【更新】BearCLI、Claude 连接器与 MCP 服务器 - 少数派 记了上千条流水,还是看不懂财务?我做了一个让 AI 读懂账本的工作台 - 少数派 MINI R56 升级原厂 Sport 模式 - 少数派 新玩意 | 一棵柠檬树(仿真版) - 少数派 Momenta的“物理AI”野望,需迈过“含摩量”这道关 - 少数派 网页直接投屏控制手机!NAS一键部署PandaScrcpy,流畅丝滑可远程。 - 少数派 众测|邀你一同探索随身 AI 硬件入口 YoooClaw C·ONE - 少数派 2050大会:分享时间是真诚 参会记 - 少数派 iPad 赋能电影创作:国内首部宣纸手绘长片《燃比娃》的幕后故事 - 少数派 AI的审美:我用 8 个大模型给 100 张旅行照片打分 - 少数派 普通人如何破圈?去参加一个本地协会 - 少数派 把极空间的图标全换了,主题DIY全攻略打造你的专属NAS桌面 - 少数派 电子便签墙,帮你实现便签自由 - 少数派 我如何用三个 CLI 工具取代文档创建需求 - 少数派 原来真的有人可以玩一辈子 - 少数派 社区速递 139 | 派友热议三月买了啥、复古单反尼康 Df 体验 - 少数派 06 作品的赏析与评价 - 少数派 TDS REVIEW|索尼 WF-1000XM6 降噪真无线耳机体验 - 少数派 35.98万起售的第二代腾势D9,我看重的不是堆料,而是不凑合 - 少数派 鼠须管 Squirrel 皮肤配置指北 - 少数派 从watch ultra2换到redmi watch6 - 少数派 派早报:阿里巴巴发布视频生成模型 HappyHorse 1.0 等 - 少数派 别迷信1M - 少数派 家人们天塌了!网盘“大封杀”,多个渠道多条路,NAS部署PanHub - 少数派 AI与人勾心斗角!NAS一键部署AI狼人杀,假日休闲必备。 - 少数派 电商必备!Comfyui工作流批量生图插件,一次生成12张!支持Nano banana pro模型 - 少数派 Comfyui工作流配置Gpt-image-2模型教程,0.03/张 - 少数派 OpenClaw第三方APi怎么配置?可使用Gpt-image-2模型 - 少数派 会员社区话题精选 Ep. 103 - 少数派
20中数组去重的方法20种数组去重的方法 - 少数派
2025-05-30 · via 少数派

开始

本文有很多问题,并没有直接给出答案,大伙有自己思考的可以评论区留言。关于时间复杂度只是一个大体的估计。20种只能说保守了20种都是单论思路而已,暂时没想到更多的思路,有其他方法的可以评论区留言。

easy模式

此时我们有一个极其简单的数组,它可能包含也不包含重复项。我们需要删除重复项并将唯一值放入新数组中。

const names = ["a","b","c","d","e","a","b"];

new Set

时间复杂度:O(n^2), 但扩展符运算符耗费时间有点多,一般推荐

最简单的,new Set去重

let newNames = [...new Set(names)]

new Set

时间复杂度:O(n^2), 比扩展运算符还费劲,一般推荐

let newNames = Array.from(new Set(names))

new Map

时间复杂度:O(n^2), 一般推荐 通过new Map原型上的方法去重。

function dealArr (a) {
  let newArr = []
  let map = new Map()
  for(let i = 0;i<a.length;i++){
    if (!map.has(a[i])) {
      map.set(a[i], true)
      newArr.push(a[i])
    }
  };
  return newArr
}

笨蛋双重for循坏

感觉实在没什么好说的,就纯暴力去重

function dealArr(a){
    let len = a.length;
    for(let i = 0; i < len; i++) for(let j = i + 1; j < len; j++) 
        if(a[j] == a[i]){
            a.splice(j,1);
            j--;
            len--;
        }
    return a;
}
function dealArr(a) {
  let b = [];
  for (let i = a.length - 1; i >= 0; i--) {
    for (let j = a.length - 1; j >= 0; j--) {
      if (a[i] == a[j] && i != j) {
        delete a[j];
      }
    }
    if (a[i] != undefined) b.push(a[i]);
  }
  return b;
}

单for循坏

时间复杂度:O(n), 它真的太快了,它是所有种类的方法里最快的,大伙可以试一试, 推荐

for循坏+hash查找

function dealArr(a) {
    let obj = {};
    let out = [];
    let len = a.length;
    let j = 0;
    for(let i = 0; i < len; i++) {
         let item = a[i];
         if(obj[item] !== 1) {
               obj[item] = 1;
               out[j++] = item;
         }
    }
    return out;
}

下面这种会快一点。

function dealArr(a) {
  obj = {};
  for (let i = 0; i < a.length; i++) {
    obj[a[i]] = true;
  }
  return Object.keys(obj);
}

for and includes

时间复杂度:O(n^2), 不推荐

for循环 + includes判断,includes会循坏到找到为止或者全部,所以挺慢的。

function dealArr(a) {
    let newArr = [];
    let j = 0;
    for (i = 0; i < a.length; i++) {
        let current = a[i];
        if (!newArr.includes(current)) newArr[j++] = current;
    }
    return newArr;
}

for and indexOf

时间复杂度:O(n^2), 不推荐

for循环 + indexof查找,indexOf会找到第一个为止或者全部。

function dealArr(a) {
    let newArr = [];
    let j = 0;
    for (i = 0; i < a.length; i++) {
        let current = a[i];
        if (newArr.indexOf(current) < 0) newArr[j++] = current;
    }
    return newArr;
}

for and lastIndexOf

时间复杂度:O(n^2), 不推荐

没啥好说的,其实和indexOf一样只是正反序查找的区别而已,问就是慢

function dealArr(a) {
    let newArr = [];
    let j = 0;
    for (i = 0; i < a.length; i++) {
        let current = a[i];
        if (newArr.lastIndexOf(current) < 0) newArr[j++] = current;
    }
    return newArr;
}  

for and newArr

相比哈希也慢

一个新数组和原数组对比,不同则放在新数组,最后返回。

function dealArr(a) {
    let newArr = [a[0]];
    for (let i = 1; i < a.length; i++) {
        let repeat = false;
        for (let j = 0; j < newArr.length; j++) {
            if (a[i] === newArr[j]) {
                repeat = true;
                break;
            }
        }
        if (!repeat) {
            newArr.push(a[i]);
        }
    }
    return newArr;
}

for and sort

想想有什么问题

先将原数组排序,再与相邻的进行比较,如果不同则存入新数组。

function dealArr(a) {
    let formArr = a.sort()
    let newArr=[formArr[0]]
    for (let i = 1; i < formArr.length; i++) {
        if (formArr[i]!==formArr[i-1]) newArr.push(formArr[i])
    }
    return newArr
}

splice

O(n^2),特别慢

function dealArr(arr) {
    let i,j,len = arr.length;
    for (i = 0; i < len; i++) {
        for (j = i + 1; j < len; j++) {
            if (arr[i] == arr[j]) {
                arr.splice(j, 1);
                len--;
                j--;
            }
        }
    }
    return arr;
}

filter and indexOf

时间复杂度:O(n^2)一般推荐

filter的本质相当于,在每一个元素上添加检查,检查该元素在数组中的第一个位置是否等于当前位置indexof是找到第一个符合条件的元素。重复元素在数组里的位置是与找到的第一个不同的。

let newNames = names.filter(function(item, index) {
    return names.indexOf(item) == index;
})

但其实上述方法不是很好,因为可能你会操作到原数组,导致原数据变化,那么我们可以直接用filter的第三个参数来做这件事,保证原数据的不可变性。

let newNames = names.filter(function(item, index, self) {
    return self.indexOf(item) == index;
})

filter and sort

时间复杂度:O(n)- O(n^2)不推荐

就是先对数组进行排序,然后删除与前一个元素相等的每个元素。大家也可以想想这方法有啥问题。提示:排序。

  let newNames =  a.sort().filter(function(item, index, self) {
        return !index || item != self[index - 1];
   });

reduce

实在是太慢了,不推荐

reduce果然是js里最完美的api

let newNames = names.reduce(function(a,b){
    if (a.indexOf(b) < 0 ) a.push(b);
    return a;
  },[]);

笨蛋hashMap

时间复杂度:O(n)一般

这个方法有点笨,通过哈希表查找fiter,大伙可以想一想缺陷是什么。(提示:对象,key。 测试用例: [1, '1']。)

function dealArr(a) {
    let seen = {};
    return a.filter(function(item) {
        return seen.hasOwnProperty(item) ? false : (seen[item] = true);
    });
}

Normal模式

easy模式下我们都只处理一些基数组,接下来我们处理一下数组对象+基数组

一般聪明的hashMap

一般聪明的hash,大伙看到这应该能明白上面的问题是什么了吧。经过一点点优化,我们对原始值和引用对象分开处理,到这它已经有了处理对象引用重复的能力了,但是它确实还不够聪明

就像这样

function dealArr(a) {
    let prims = {"boolean":{}, "number":{}, "string":{}}, objs = [];

    return a.filter(function(item) {
        let type = typeof item;
        if(type in prims)
            return prims[type].hasOwnProperty(item) ? false : (prims[type][item] = true);
        else
            return objs.indexOf(item) >= 0 ? false : objs.push(item);
    });
}

聪明的hashMap

我们有时候可以写一个通用的函数,通过回调函数来优雅的完成过滤,比如这样!

大家可以思考一下为什么JSON.stringify,能完成过滤。

function dealArrByBey(a, key) {
    let obj = {};
    return a.filter(function(item) {
        let k = key(item);
        return obj.hasOwnProperty(k) ? false : (obj[k] = true);
    })
}

稍微炫一点

但这都es6了还这么玩不太合适,这样会好看一些。

可以看到过滤了后面的b.

function dealArrByBey(a, key) {
    let obj = new Set();
    return a.filter(item => {
        let k = key(item);
        return obj.has(k) ? false : obj.add(k);
    });
}

特别炫

感觉这么写就特别开心了,虽然可读性不好,而且也不是很快,但它很帅啊。但这三种方法,是有点区别的,上面两种方法是保留第一个,过滤掉后面的,而这种方法保留的是最后一个,大伙可以思考一下为什么

function dealArrByBey(a, key) {
    return [
        ...new Map(
            a.map(x => [key(x), x])
        ).values()
    ]
}

hard模式

珂里化 + 链式调用

em,都写到这了,我们可以再进阶再抽象一下,让我们的去重也可以写成一个非常抽象的链式调用。多重箭头函数其实就是函数珂里化的语法糖(fn(a,b,c)改造成fn(a)(b)(c)),让我们完成一个参数对齐

const apply = f => a => f(a);

const flip = f => b => a => f(a) (b);

const uncurry = f => (a, b) => f(a) (b);

const push = x => xs => (xs.push(x), xs);

const fold = f => acc => xs => xs.reduce(uncurry(f), acc);

const some = f => xs => xs.some(apply(f));

const dealArrByFn = f => fold(
   acc => x => some(f(x)) (acc)
    ? acc
    : push(x) (acc)
 ) ([]);
 
const eq = y => x => x === y;
dealArrByFn(eq)(names)

总结:

关于我