JS数组求众数的最简单实现,附代码示例
(拍大腿)哎!有没有遇到过这样的问题?给你一个数组 [2,3,5,3,3,2,2],让你找出出现次数最多的数字?这时候你可能会抓耳挠腮——这玩意儿到底该怎么算啊?别慌,今天咱们就用最接地气的方式,把这道题给盘明白!
一、到底啥叫"众数"?
举个栗子啊,就像你们班考试,全班50个人里有30个都考了80分,那80分就是这次考试的众数。说白了,??众数就是一组数据中出现次数最多的那个值??。不过要注意哦,有时候可能有多个值出现次数一样多,这时候就会有多个众数。
(挠头)那在JS里具体怎么操作呢?别急,咱们一步步来。
二、手把手教你实现
第一步:先准备个计数器
咱们可以用普通对象当计数器,就像这样:
javascript复制let arr = [2,3,5,3,3,2,2]; let counter = {}; for(let num of arr) { // 如果这个数字还没记录过,就先记个0 if(!counter[num]) counter[num] = 0; // 每次遇到就+1 counter[num]++; }
这时候counter对象就会变成:
javascript复制{ '2': 3, '3': 3, '5': 1 }
(敲黑板)看到了吧?2和3都出现了3次,所以这俩都是众数。
第二步:找出最大出现次数
这时候需要找最大的那个值:
javascript复制let maxCount = Math.max(...Object.values(counter)); // 3
第三步:收集所有符合条件的数
最后遍历counter对象:
javascript复制let result = []; for(let key in counter) { if(counter[key] === maxCount) { result.push(Number(key)); // 记得转成数字类型 } }
这时候result就是[2,3]啦!
三、完整代码一锅端
把上面的步骤打包成函数:
javascript复制function findMode(arr) { // 第一步:统计次数 const counter = {}; for(const num of arr) { counter[num] = (counter[num] || 0) + 1; } // 第二步:找最大次数 const maxCount = Math.max(...Object.values(counter)); // 第三步:收集结果 const result = []; for(const num in counter) { if(counter[num] === maxCount) { result.push(Number(num)); } } return result.length === 1 ? result[0] : result; } // 测试一下 console.log(findMode([2,3,5,3,3,2,2])); // [2,3] console.log(findMode([1,2,3,4,5])); // [1,2,3,4,5]
(突然想到)对了!这里有个小陷阱要注意:当所有元素出现次数都为1时,整个数组都会被当作众数返回,这个逻辑是故意这么设计的,因为确实每个数都是出现次数最多的嘛!
四、优化代码的小技巧
技巧1:用Map代替对象
如果数组里有特殊类型的数据,比如对象、NaN,用Map会更靠谱:
javascript复制const counter = new Map(); arr.forEach(num => { counter.set(num, (counter.get(num) || 0) + 1); });
技巧2:一行代码统计次数
用reduce方法装个逼:
javascript复制const counter = arr.reduce((acc, num) => { acc[num] = (acc[num] || 0) + 1; return acc; }, {});
五、实战中的常见问题
-
??空数组怎么办???
记得在最开始加个判断:javascript复制
if(arr.length === 0) throw new Error("数组不能为空!");
-
??处理大数组会卡吗???
这个方案时间复杂度是O(n),处理百万级数据都没问题。不过要注意??Object.values??这个方法在超大数据量下可能会有点吃力。 -
??能不能用ES6新语法???
当然可以!比如用展开运算符处理Map:javascript复制
const maxCount = Math.max(...counter.values());
六、个人踩坑经验谈
刚开始学的时候,我总想着用各种高阶函数装逼,结果搞出一堆花里胡哨的代码。后来被组长骂了才知道,??代码的可读性比炫技更重要??。比如这个求众数的需求,用最朴实的for循环反而更容易维护。
还有一次遇到个奇葩需求:要同时返回众数和出现次数。这时候只要稍微改改返回值就行:
javascript复制return { mode: result, count: maxCount };
(托腮)说到底啊,编程就像做菜,同样的食材用不同的做法都能做出美味。关键是要根据实际情况选择最合适的烹饪方式。下次遇到类似的问题,希望你能自信地说:"这题我会!" 然后刷刷刷写出既简洁又高效的代码。记住了,编程没有标准答案,能解决问题的代码就是好代码!
本文由嘻道妙招独家原创,未经允许,严禁转载