JS 正则数组去重分析
分类: JAVASCRIPT
| 浏览人数: 6696 | 赞: 0 | 发表于: 2014-12-04 | _by: liuzw
故事是这样开始的……
在一个夜黑风高的晚上~前端群里空然有人问怎么得到一个数组重复的部分,我立马想到去重后和原数组求差集,于是……发现一个用正则去重的逆天写法,就是下面这个像天书一样的东西:
Array.prototype.unique = function(){ return this.sort() .join(",,") .replace(/(,|^)([^,]+)(,,\2)+(,|$)/g,"$1$2$4") .replace(/,,+/g,",") .replace(/,$/,"") .split(","); }
为了方便我把代码分成了N多行,本来是一行的return语句,下面开始一行行分析。
第一行是对数组排序,这个不用多说。
第二行将数组用两个逗号 [,,] 分隔。假设我的数组为:
var a = [1,2,3,4,2,3,4,4];
那么排序后再用[,,]分隔的结果是:
1,,2,,2,,3,,3,,4,,4,,4
那么重点来了,第四行,先来分析正则,第一个括号(,|^)表示以逗号或者字符串起始位置开始。
第二个括号([^,]+)表示任意非逗号字符重复1次或更多次,在我们分隔后的字符串里只能匹配到数字。
最重要的第三个括号(,,\2)+ 要特别注意这里的+并不是JS里的连接符,而是表示第三个括号匹配到的内容重复1次或更多次,那么第三个括号是什么意思呢?两个逗号 [,,] 表示两个逗号开始,\2表示第二个括号匹配到的内容,看到这里应该在概知道了吧。
第四个括号表示以逗号或者字符最末为结束,那么这四个连起来应用到我们上面的字符串上就会匹配到以下三个数据:
(,)(2)(,,2)(,) //,2,,2, (,)(3)(,,3)(,) //,3,,3, (,)(4)(,,4,,4)($) //,4,,4,,4
其中括号是我加的,注释才是真实匹配结果,在正则中括号也称为分组,而$号表示结束位置,每个括号里的内容对应上面的分析结果。
匹配出来后怎么去重呢?看replace函数的第二个参数: '$1$2$4' $1即表示第一个分组,也就是第一个括号里匹配到的内容,意思是用1,2,4三个括号匹配到的内容拼成的字符串替换匹配到的内容,执行结果为:
1,,2,,3,,4
这样就达到了去重的目的,第5、6、7行就是把 [, ,]替换成 [,] 再把最后的 [,] 去掉,最后用split再分割成数组,我们的结果最后没有 [,] 可能是作者为了兼容不同浏览器吧。
至此,去重目的达到了。