今天有朋友提到js中关于如何删除数组中重复项最优的写法,我想起了09年淘宝 怿飞(圆心)在他的“删除数组中重复项(uniq)”文章提到的那句话:“没有最好,只有最合适的方式”!
深表赞同,他在文中给出了一个方法,在这里我还是全部拷贝一下吧:
var uniq = function (arr) { var a = [], o = {}, i, v, cv, // corrected value len = arr.length; if (len < 2) { return arr; } for (i = 0; i < len; i++) { v = arr[i]; /* closurecache 提供的函数中使用的是 cv = v + 0;, * 这样就无法辨别类似[1, 10, "1", "10"]的数组, * 因为运算后 => 1, 10, 10, 100,很明显,出现了重复的标示符。 * 加前面就难道没问题吗? * 有的:数组中不能出现类似01 、001,以 0 开头的数字, * 但适用性比原先更广。 */ cv = 0 + v; if (!o[cv]) { a.push(v); o[cv] = true; } } return a; }
以上函数比较适合那些由数字组成的数组,正如作者所说的,识别不了类似:[1, 10, "1", "10"] 这样的数组,其实只需要稍作修改即可
cv = 0 + v; ====> cv = v-0;
很神奇吧,js中的减法规则里面有一条类似:减号两边如果有一边是数字,那么另一边先转型为数字,再进行运算
但如果出现了类似这样的数组:[0, 1, "0", "null", null, 'str'],要求剔除相同项(需求中1与“1”是相同项),怎办?
还是将上面的函数稍作修改:将 cv = 0+v 改成 cv = v+""
var uniq = function(arr){ var a = [], o = {}, i = 0, v, cv, len = arr.length; if(len<2){ return arr; } for(;i<len;i++){ v = arr[i]; cv = v+""; //全部转化成字符串 if(!o[cv]){ a.push(v); o[cv] = true; } } return a; };
遇到好东西,总也忍不住拿来品玩一下,望怿飞勿怪!