JavaScipt数组去重

	// 方法1  双层循环
	// var array = [1,1,"1","1"];
	// function unique(array) {
	// 	// res用来存储结果
	// 	var res = [];
	// 	for(var i = 0; i < array.length; i++) {
	// 		for(var j = 0; j < res.length; j++) {
	// 			if(array[i]  === res[j]) {
	// 				break;
	// 			}
	// 		}
	// 		// 如果array[i]是惟一的,那么执行完循环,j等于res.length
	// 		if(j === res.length) {
	// 			res.push(array[i])
	// 		}
	// 	}
	// 	return res;
	// }
	// console.log(unique(array)); //[1,"1"]
	// 在这个方法中使用循环嵌套,最外层循环array,里面循环res,如果array[i]的值跟res[j]的值相等,就跳出循环;如果不等于就说明元素是惟一的,这时候j的值就会等于res的长度,根据这个特点进行判断,将值添加进res


	// 方法2  indexOf -1
	// 使用indexOf可以简化内层循环
	// var array = [2,2,"2","2"];
	// function unique(array) {
	// 	var res = [];
	// 	for(var i = 0; i < array.length; i++) {
	// 		var current = array[i];
	// 		if(res.indexOf(current) === -1) {
	// 			res.push(current)
	// 		}
	// 	}
	// 	return res;
	// }
	// console.log(unique(array));  //[2,"2"]


	// 方法3  ES6
	// 可以使用Set和Map数据结构,以Set为例,ES6提供了新的数据结构Set,它类似于数组,但是成员的值都是唯一的,没有重复的值
	// Set
	// var array = [3,3,"3","3"];
	// function unique(array) {
	// 	return Array.from(new Set(array));
	// }
	// console.log(unique(array));  //[3,"3"]
		// 可以简化为:
		// function unique(array) {
		// 	return [...new Set(array)];
		// }
		// console.log(unique(array));  //[3,"3"]
			// 还可以简化为: 
			// var unique = (a) => [...new Set(a)]

	// Map
	// var array = [3,3,"3","3"];
	// function unique(array) {
	// 	const seen = new Map()
	// 	return array.filter((a) => !seen.has(a) && seen.set(a,1))
	// }
	// console.log(unique(array));  //[3,"3"]


	// 方法4  排序后去重
	// 先将要去重的数组使用sort方法排序后,相同的值会被排在一起,然后就可以只判断当前元素与上一个元素知否相同,相同就说明重复,不相同就添加进res
	// var array = [4,4,"4","4"];
	// function unique(array) {
	// 	var res = [];
	// 	var sortedArray = array.concat().sort();
	// 	var seen;
	// 	for(var i = 0; i < sortedArray.length; i++) {
	// 		if(!i || seen !== sortedArray[i]) {
	// 			res.push(sortedArray[i]);
	// 		}
	// 		seen = sortedArray[i];
	// 	}
	// 	return res;

	// }
	// console.log(unique(array));  //[4,"4"]
	// 如果对一个已经排好序的数组去重,这种方法的效率高于indexOf

	// 方法5  filter
	// 使用此方法来简化外层循环
	// var array = [5,5,"5","5"];
	// function unique(array) {
	// 	var res = array.filter(function(item,index,array) {
	// 		return array.indexOf(item) === index;
	// 	})
	// 	return res;
	// }
	// console.log(unique(array));  //[5,"5"]

	// 排序去重的方法:
	// var array = [5,5,"5","5"];
	// function unique(array) {
	// 	return array.concat().sort().filter(function(item,index,array) {
	// 		return !index || item !== array[index -1]
	// 	})
	// }
	// console.log(unique(array));

	// 方法6 Object键值对
	// 这种方法是利用一个空的 Object 对象,我们把数组的值存成 Object 的 key 值,比如 Object[value1] = true,在判断另一个值的时候,如果 Object[value2]存在的话,就说明该值是重复的。示例代码如下:

// var array = [1, 2, 1, 1, '1'];

// function unique(array) {
//     var obj = {};
//     return array.filter(function(item, index, array){
//         return obj.hasOwnProperty(item) ? false : (obj[item] = true)
//     })
// }

// console.log(unique(array)); // [1, 2]
// 我们可以发现,是有问题的,因为 1 和 '1' 是不同的,但是这种方法会判断为同一个值,这是因为对象的键值只能是字符串,所以我们可以使用 typeof item + item 拼成字符串作为 key 值来避免这个问题:

// var array = [1, 2, 1, 1, '1'];

// function unique(array) {
//     var obj = {};
//     return array.filter(function(item, index, array){
//         return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
//     })
// }

// console.log(unique(array)); // [1, 2, "1"]
// 然而,即便如此,我们依然无法正确区分出两个对象,比如 {value: 1} 和 {value: 2},因为 typeof item + item 的结果都会是 object[object Object],不过我们可以使用 JSON.stringify 将对象序列化:

// var array = [{value: 1}, {value: 1}, {value: 2}];

// function unique(array) {
//     var obj = {};
//     return array.filter(function(item, index, array){
//         console.log(typeof item + JSON.stringify(item))
//         return obj.hasOwnProperty(typeof item + JSON.stringify(item)) ? false : (obj[typeof item + JSON.stringify(item)] = true)
//     })
// }

// console.log(unique(array)); // [{value: 1}, {value: 2}]

// 方法7 unique API
// 写一个名为 unique 的工具函数,根据一个参数 isSorted 判断传入的数组是否是已排序的,如果为 true,就判断相邻元素是否相同,如果为 false,就使用 indexOf 进行判断

// var array1 = [1, 2, '1', 2, 1];
// var array2 = [1, 1, '1', 2, 2];

// // 第一版
// function unique(array, isSorted) {
//     var res = [];
//     var seen = [];

//     for (var i = 0, len = array.length; i < len; i++) {
//         var value = array[i];
//         if (isSorted) {
//             if (!i || seen !== value) {
//                 res.push(value)
//             }
//             seen = value;
//         }
//         else if (res.indexOf(value) === -1) {
//             res.push(value);
//         }        
//     }
//     return res;
// }

// console.log(unique(array1)); // [1, 2, "1"]
// console.log(unique(array2, true)); // [1, "1", 2]
// 优化

// 新需求:字母的大小写视为一致,比如'a'和'A',保留一个就可以了!

// 虽然可以先处理数组中的所有数据,比如将所有的字母转成小写,然后再传入unique函数,但是有没有方法可以省掉处理数组的这一遍循环,直接就在去重的循环中做呢?

// var array3 = [1, 1, 'a', 'A', 2, 2];

// // 第二版
// // iteratee 英文释义:迭代 重复
// function unique(array, isSorted, iteratee) {
//     var res = [];
//     var seen = [];

//     for (var i = 0, len = array.length; i < len; i++) {
//         var value = array[i];
//         var computed = iteratee ? iteratee(value, i, array) : value;
//         if (isSorted) {
//             if (!i || seen !== computed) {
//                 res.push(value)
//             }
//             seen = computed;
//         }
//         else if (iteratee) {
//             if (seen.indexOf(computed) === -1) {
//                 seen.push(computed);
//                 res.push(value);
//             }
//         }
//         else if (res.indexOf(value) === -1) {
//             res.push(value);
//         }        
//     }
//     return res;
// }

// console.log(unique(array3, false, function(item){
//     return typeof item == 'string' ? item.toLowerCase() : item
// })); // [1, "a", 2]
// 在这一版也是最后一版的实现中,函数传递三个参数:

// array:表示要去重的数组,必填

// isSorted:表示函数传入的数组是否已排过序,如果为 true,将会采用更快的方法进行去重

// iteratee:传入一个函数,可以对每个元素进行重新的计算,然后根据处理的结果进行去重

 

posted @ 2018-03-27 00:21  spksth  阅读(127)  评论(0编辑  收藏  举报