咱们先来看下面的例子,固然来源与网络,地址《删除数组中多个不连续的数组元素的正确姿式》html
咱们如今将数组中全部的‘ a’ 元素删除:数组
var arr = ['a', 'a', 'b', 'c', 'd', 'a', 'a', 'e', 'g', 'a', 'f'];
arr.forEach(function(value, index) {
value === 'a' ? arr.splice(index, 1) : '';
})
console.log(arr); //["a", "b", "c", "d", "a", "e", "g", "f"]
只要相邻的‘ a’ 元素, 都没被删除, splice不但能够删除元素自己, 还同时能够减小数组长度( 就是抹去一切痕迹),
这样致使后续的数组元素会代替已经删除的元素的位置, 可是循环是按照数组的下标按顺序删除, 这样就会漏掉迁移的元素。浏览器
看到网上有网友在说使用delete进行操做,以下:网络
var arr = ['a', 'a', 'b', 'c', 'd', 'a', 'a', 'e', 'g', 'a', 'f']; arr.forEach(function(value, index) { value === 'a' ? delete arr[index] : ''; }) console.log(arr); //[2: "b", 3: "c", 4: "d", 7: "e", 8: "g", 10: "f"]
可是获得的arr实际上是一个很是规的数组了,也就是说其实delete主要是用于对对象属性的操做。这确实要根据本身的需求来了。数据结构
固然简单的实现以下:函数
var arr = ['a', 'a', 'b', 'c', 'd', 'a', 'a', 'e', 'g', 'a', 'f']; var newArr = arr.filter(function(key) { return key !== 'a' }) console.log(newArr); //["b", "c", "d", "e", "g", "f"]
下面总结下经常使用实现方式。oop
双层循环,外层循环元素,内层循环时比较值post
若是有相同的值则跳过,不相同则push进数组this
Array.prototype.distinct = function(){ var arr = this, result = [], i, j, len = arr.length; for(i = 0; i < len; i++){ for(j = i + 1; j < len; j++){ if(arr[i] === arr[j]){ j = ++i; } } result.push(arr[i]); } return result; } var arra = [1,2,3,4,4,1,1,2,1,1,1]; arra.distinct(); //返回[3,4,2,1]
双层循环,外层循环元素,内层循环时比较值url
值相同时,则删去这个值
注意点
:删除元素以后,须要将数组的长度也减1.
Array.prototype.distinct = function (){ var arr = this, 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; }; var a = [1,2,3,4,5,6,5,3,2,4,56,4,1,2,1,1,1,1,1,1,]; var b = a.distinct(); console.log(b.toString()); //1,2,3,4,5,6,56
优势:简单易懂
缺点:占用内存高,速度慢
Array.prototype.distinct = function (){ var arr = this, i, obj = {}, result = [], len = arr.length; for(i = 0; i< arr.length; i++){ if(!obj[arr[i]]){ //若是能查找到,证实数组元素重复了 obj[arr[i]] = 1; result.push(arr[i]); } } return result; }; var a = [1,2,3,4,5,6,5,3,2,4,56,4,1,2,1,1,1,1,1,1,]; var b = a.distinct(); console.log(b.toString()); //1,2,3,4,5,6,56
运用递归的思想
先排序,而后从最后开始比较,遇到相同,则删除
Array.prototype.distinct = function (){ var arr = this, len = arr.length; arr.sort(function(a,b){ //对数组进行排序才能方便比较 return a - b; }) function loop(index){ if(index >= 1){ if(arr[index] === arr[index-1]){ arr.splice(index,1); } loop(index - 1); //递归loop函数进行去重 } } loop(len-1); return arr; }; var a = [1,2,3,4,5,6,5,3,2,4,56,4,1,2,1,1,1,1,1,1,56,45,56]; var b = a.distinct(); console.log(b.toString()); //1,2,3,4,5,6,45,56
indexOf
以及forEach
首先若是你的浏览器是低版本不支持indexOf与forEach方法,那么能够先先对浏览器Array对象进行支持indexOf和forEach的polyfill
Array.prototype.indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, j = this.length; i < j; i++) { if (this[i] === item) { return i; } } return -1; } Array.prototype.forEach = Array.prototype.forEach || function(callback, thisArg) { if (!callback || typeof callback !== 'function') return; for (var i = 0, j = this.length; i < j; i++) { callback.call(thisArg, this[i], i, this); } }
去重方法:
Array.prototype.distinct = function (){ var arr = this, result = [], len = arr.length; arr.forEach(function(v, i ,arr){ //这里利用map,filter方法也能够实现 var bool = arr.indexOf(v,i+1); //从传入参数的下一个索引值开始寻找是否存在重复 if(bool === -1){ result.push(v); } }) return result; }; var a = [1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,2,1,23,1,23,2,3,2,3,2,3]; var b = a.distinct(); console.log(b.toString()); //1,23,2,3
Array.prototype.distinct = function (){ var arr = this, ret = []; arr.forEach(function(e, i, array) { if (array.indexOf(e) === i) { ret.push(e); } }); return ret; }; var a = [1,2,3,4,5,6,5,3,2,4,56,4,1,2,1,1,1,1,1,1,]; var b = a.distinct(); console.log(b.toString()); //1,2,3,4,5,6,56
Set数据结构,它相似于数组,其成员的值都是惟一的。
利用Array.from将Set结构转换成数组
function dedupe(array){ return Array.from(new Set(array)); } dedupe([1,1,2,3]) //[1,2,3]
拓展运算符(...)内部使用for...of循环
let arr = [1,2,3,3]; let resultarr = [...new Set(arr)]; console.log(resultarr); //[1,2,3]
固然以上方法能够不用写到Array的原型上,单独写一个方法,传递数组当参数也是能够的。
参考地址:http://www.cnblogs.com/leonwang/p/4845576.html
文章更新于2017-12-07