/**
*
* @authors Your Name (you@example.org)
* @date 2018-10-11 15:05:02
* @version $Id$
*/
//IE8以下不支持数组的indexOf方法,先对浏览器Array对象进行支持indexOf和forEach的polyfill
Array.prototype.indexOf = Array.prototype.indexOf || function(item) {
for( var i=0, j=this.length; i<j; i++ ) {
if( item === this[i] ) {
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.map = Array.prototype.map || function(callback, thisArg) {
if( !callback || typeof callback !== 'function' ) return;
var newArr = [];
for( var i=0, j=this.length; i<j; i++ ) {
var val = callback.call( thisArg, this[i], i, this );
newArr[newArr.length] = val;
}
}
/**
* 遍历数组,建立新数组,利用indexOf判断是否存在于新数组中,不存在则push到新数组,最后返回新数组
* @param {[type]} array [description]
* @return {[type]} [description]
*/
function uniq1(array) {
var temp = [];
for( var i=0, j=array.length; i<j; i++ ) {
if( temp.indexOf(array[i]) == -1 ) {
temp.push(array[i]);
}
}
return temp;
}
/**
* 对象键值法去重(哈希算法去重)【速度最快, 占空间最多(空间换时间)】
* 遍历数组,利用object对象保存数组值,判断数组值是否已经保存在object中,未保存则push到新数组并用object[arrayItem]=1的方式记录保存
* @param {[type]} array [description]
* @return {[type]} [description]
*/
function uniq2(array) {
var temp = {}, ret = [];
for( var i=0, j=array.length; i<j; i++ ) {
if(!temp[array[i]]) {
temp[array[i]] = 1;
ret.push(array[i]);
}
}
return ret;
}
/**
* 对象键值法去重【速度最快, 占空间最多(空间换时间)】
* 新建一js对象以及新数组,遍历传入数组时,判断值是否为js对象的键,不是的话给对象新增该键并放入新数组
* 注意点:判断是否为js对象键时,会自动对传入的键执行“toString()”,不同的键可能会被误认为一样,例如n[val]-- n[1]、n["1"],解决上述问题还是得调用“indexOf”
* @param {[type]} array [description]
* @return {[type]} [description]
*/
function uniq3(array) {
var temp = {}, ret = [], val, type;
for( var i=0, j=array.length; i<j; i++ ) {
val = array[i];
type = typeof val;
if( !temp[val] ) {
temp[val] = [type];
ret.push(val);
}
else if( temp[val].indexOf(type) < 0 ) {
temp[val].push(type);
ret.push(val);
}
}
return ret;
}
/**
* 数组下标法
* 如果当前数组的第i项在当前数组中第一次出现的位置不是i,那么表示第i项是重复的,忽略掉。否则存入结果数组。
* @param {[type]} array [description]
* @return {[type]} [description]
*/
function uniq4(array) {
var temp = [];
//for循环实现
for( var i=0, j=array.length; i<j; i++ ) {
if( array.indexOf(array[i]) == i ) {
temp.push(array[i]);
}
}
//forEach实现
/*array.forEach(function(val, index, array) {
if( array.indexOf(val) === index ) {
temp.push(val);
}
});*/
//map实现
/*array.map(function(val, index, array) {
if( array.indexOf(val) === index ) {
temp.push(val);
}
});*/
return temp;
}
/**
* 排序后相邻去除法
* 给传入数组排序,排序后相同值相邻,遍历时,新数组只加入不与前一值重复的值。
* @param {[type]} array [description]
* @return {[type]} [description]
*/
function uniq5(array) {
array.sort();
var temp = [array[0]];
for( var i=1, j=array.length; i<j; i++ ) {
if( array[i] !== temp[temp.length-1] ) {
temp.push(array[i]);
}
}
return temp;
}
/**
* 优化遍历数组法
* 双层循环,外层循环元素,内层循环时比较值,如果有相同的值则跳过,不相同则push进数组
* @param {[type]} array [description]
* @return {[type]} [description]
*/
function uniq6(array) {
var temp = []; //存储值
// var index = []; //存储下标
for( var i=0, j=array.length; i<j; i++ ) {
for( var k=i+1; k<j; k++ ) {
if( array[i] === array[k] ) {
i++;
k=i;
}
}
temp.push(array[i]);
// index.push(i);
}
return temp;
}
/**
* 利用splice直接在原数组进行操作
* 双层循环,外层循环元素,内层循环时比较值,值相同时,则删去这个值
* 注意点:删除元素之后,需要将数组的长度也减1
* @param {[type]} array [description]
* @return {[type]} [description]
*/
function uniq7(array) {
var len = array.length;
for( var i=0; i<len; i++ ) {
for( var k=i+1; k<len; k++ ) {
if( array[i] === array[k] ) {
array.splice(k,1);
len--;
k--;
}
}
}
return array;
}
/**
* 利用ES6的set:利用Array.from将Set结构转换成数组
* @param {[type]} array [description]
* @return {[type]} [description]
*/
function uniq8(array) {
return Array.from(new Set(array));
}
/**
* 利用ES6的set:拓展运算符(...)内部使用for...of循环
* @param {[type]} array [description]
* @return {[type]} [description]
*/
function uniq9(array) {
return [...new Set(array)];
}
var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq1(aa));
console.log(uniq2(aa));
console.log(uniq3(aa));
console.log(uniq4(aa));
console.log(uniq5(aa));
console.log(uniq6(aa));
console.log(uniq7(aa));
console.log(uniq8(aa));
console.log(uniq9(aa));
//输出结果:
// (9) [1, 2, "2", 4, 9, "a", 3, 5, 6]
// (8) [1, 2, 4, 9, "a", 3, 5, 6]
// (9) [1, 2, "2", 4, 9, "a", 3, 5, 6]
// (9) [1, 2, "2", 4, 9, "a", 3, 5, 6]
// (9) [1, "2", 2, 3, 4, 5, 6, 9, "a"]
// (9) [1, "2", 2, 3, 4, 5, 6, 9, "a"]
// (9) [1, "2", 2, 3, 4, 5, 6, 9, "a"]
// (9) [1, "2", 2, 3, 4, 5, 6, 9, "a"]
// (9) [1, "2", 2, 3, 4, 5, 6, 9, "a"]