Open YvetteLau opened 5 years ago
// 第一种方式
var arr = [1, 2, 2, 4, 1, 5, 8, 10];
var newArray = [...new Set(arr)];
// 第二种
var arr = [1, 2, 2, 4, 1, 5, 8, 10];
var newArray = [];
for (let i = 0; i < arr.length; i++) {
let one = arr[i];
if(newArray.indexOf(one)<0){
newArray.push(one);
}
}
function removeItem(list) {
if(!list){
return [];
}else{
let set = new Set(list);
return Array.from(set);
}
}
console.log(removeItem([1,1,1,1,3,4,2]));//[ 1, 3, 4, 2 ]
function removeItem(list) {
if(!list){
return [];
}else{
let returnList = [];
for(let i = 0; i<list.length; i++){
if(returnList.indexOf(list[i]) < 0){
returnList.push(list[i]);
}
}
return returnList;
}
}
console.log(removeItem([1,1,1,1,3,4,2]));//[ 1, 3, 4, 2 ]
应该还有很多,暂时想到这些,先工作了,一会看大佬操作.
1: 最简单数组去重法
function uniq(array){
var temp = []; //一个新的临时数组
for(var i = 0; i < array.length; i++){
if(temp.indexOf(array[i]) == -1){
temp.push(array[i]);
}
}
return temp;
}
2: set 对象
function uniq(array){
return […new Set(array)];
}
3: 先排序后相邻去除法
function uniq(array){
array.sort();
var temp=[array[0]];
for(var i = 1; i < array.length; i++){
if( array[i] !== temp[temp.length-1]){
temp.push(array[i]);
}
}
return temp;
}
4: 数组下标法
function uniq(array){
var temp = [];
for(var i = 0; i < array.length; i++) {
//如果当前数组的第i项在当前数组中第一次出现的位置是i,才存入数组;否则代表是重复的
if(array.indexOf(array[i]) == i){
temp.push(array[i])
}
}
return temp;
}
5: 利用对象属性存在的特性,如果没有该属性则存入新数组。
function uniq(arr) {
var obj={}
var newArr=[]
for (let i = 0; i < arr.length; i++) {
if (!obj[arr[i]]) {
obj[arr[i]] = 1
newArr.push(arr[i])
}
}
return newArr
}
6: 利用数组原型对象上的includes方法
function uniq(arr) {
var newArr = []
for (var i = 0; i < arr.length; i++) {
if (!newArr.includes(arr[i])) {
newArr.push(arr[i])
}
}
return newArr
}
7: 利用数组原型对象上的 filter 和 includes方法
function uniq(arr) {
var newArr = []
newArr = arr.filter(function (item) {
return newArr.includes(item) ? '' : newArr.push(item)
})
return newArr
}
8: 利用数组原型对象上的 forEach 和 includes方法。
function uniq(arr) {
var newArr = []
array.forEach(item => {
return newArr.includes(item) ? '' : newArr.push(item)
});
return newArr
}
1.根据索引去重 function uniqcArr(arr){ var tep=[]; for(var i=0;i<arr.length;i++){ if(tem.indexof(arr[i])==-1){ tep.push(arr[i]) } } retuen tep; } 2.es6方法 function uniqcArr(array){ return […new Set(array)]; } 3.利用对象的属性 function uniqueArr(arr){ var hasmap={}; var unique=[]; for(var i=0;i<arr.length;i++){ if(!hasmap.hasOwnproperty([arr[i]])){ unique.push(arraay[i])}} return unique;}
function uniqueArr(array) {
return [...new Set(array)]
}
let arr = [1,2,2,3,3,4,5,6]
uniqueArr(arr)
function uniqueArr(array) {
let temp = [];
for(let i = 0, len = array.length; i < len; i++) {
if(temp.indexOf(array[i]) === -1) {
temp.push(arr[i])
}
}
return temp;
}
let arr = [1,2,2,3,3,4,5,6]
uniqueArr(arr)
测试模板 造一个10W数组,造一个5W数组,合并为一个15W数组进行测试
let array1 = Array.from(new Array(100000),(x,index) => {
return index
})
let array2 = Array.from(new Array(50000),(x,index) =>{
return index+index
})
let start = new Date().getTime()
console.log('begin to remove duplicates')
function distinct(a, b) {
//logic to remove duplicates
}
console.log('length after removing duplicate-', distinct(array1,array2).length)
let end = new Date().getTime()
console.log('time spent -',end-start)
第一种方法,效率最低,双循环
function distinct(a, b) {
let arr = a.concat(b);
for (let i=0, len=arr.length; i<len; i++) {
for (let j=i+1; j<len; j++) {
if (arr[i] == arr[j]) {
arr.splice(j, 1);
// splice 会改变数组长度,所以要将数组长度 len 和下标 j 减一
len--;
j--;
}
}
}
return arr
}
第二种方法
function distinct(a,b){
let arr=a.concat(b)
let result=[]
for (let i of arr) {
!result.includes(i) && result.push(i)
}
return result
}
第三种
function distinct(a,b) {
let arr = a.concat(b)
arr = arr.sort()
let result = [arr[0]]
for (let i=1,len=arr.length;i<len;i++){
arr[i]!==arr[i-1] && result.push(arr[i])
}
return result;
}
第四种
function distinct(a,b){
return Array.from(new Set([...a,...b]))
}
第五种 利用对象属性不会重复这一特性
function distinct (a,b){
let arr=a.concat(b)
let result=[]
let obj={}
for (let i of arr) {
if(!obj[i]){
result.push(i)
obj[i]=1
}
}
return result
}
Set()
是ES6提供的新的数据结构,其类似于数组,但是成员值都是唯一的,没有重复的值。利用这一特性,完成数组的去重操作。这里需要注意的是返回值也是类数组的 Set
数据结构,需要转换成数组结构。
// 这里使用扩展运算符 ... 讲 Set 结构数据转换成数组
var delRepetition = function (arr) {
return [...new Set(arr)];
}
// 也可以使用 ES6 中的 Array.from() 转换成数组
var delRepetition = function (arr) {
return Array.from(new Set(arr));
}
使用该方法比较的直观容易理解,唯一需要注意的是兼容性即可。
参考资料: ESMAScript 6 入门
Array
内置函数中提供数组元素的查询:
Array.prototype.indexOf()
搜索数组元素,并返回所在的位置,未找到返回 -1;
Array.prototype.includes()
判断数组是否包含指定的值,包含返回 true,不包含返回 false;
判断当先元素的下标是否等于查询结果的下标,如果是,则表示第一次出现,如果非表示重复出现。可以借助于Array.prototype.filter()
函数返回新的数组内容。
// 如果下标为当前元素下标,表示第一次出现
// 可以直接放入新的数组当中
var delRepetition = function (arr) {
let isN = false;
let newArr = arr.filter((currentValue, index, array) => {
// 判断当前元素是否为 NaN
// 可根据自己的需要删减
if (currentValue !== currentValue) isN = true;
return array.indexOf(currentValue) === index
})
// 如果包含有NaN元素,最后在添加上
if (isN) {
newArr.push(NaN);
}
return newArr;
}
该方法中包含了特殊类型 NaN
的检测,利用其自身不等于自身的特性进行检测,如果值中包含有NaN
元素,最后添加到数组当中。
当然也可以直接利用数组从左向右计算的特性,返回最后的结果。原理都差不多,返回新数组。
var delRepetition = function (arr) {
let isN = false;
let newArr = arr.reduce((total, currentValue) => {
if (currentValue !== currentValue) {
isN = true;
} else {
total.indexOf(currentValue) === -1 && total.push(currentValue);
}
return total;
}, []);
if (isN) newArr.push(NaN);
return newArr;
}
查询元素是否存在需要进行循环遍历,可以使用 Array.prototype.forEach()
或 for ... of
等。也可以使用 for 循环
,但是需要注意他们之间的区别,虚数组与实数组之间的转换。
使用数组的内置函数,查询新数组中是否包含有当前元素,如果不包含当前元素,则添加到新的数组当中,如果包含则跳过,这里需要摘出NaN
。
var delRepetition = function (arr) {
let newArr = [],
isN = false;
for (let v of arr) {
if (v !== v) {
isN = true;
continue;
}
if (!newArr.includes(v)) {
newArr.push(v);
}
}
if (isN) newArr.push(NaN);
return newArr;
}
先对元素排序,然后再对比插入:
var delRepetition = function (arr) {
let sArr = [].concat(arr).sort();
let newArr = [],
isN = false;
sArr.forEach((value, index, cArr) => {
if (value !== value) {
isN = true;
} else if (index === 0 || value !== cArr[index - 1]) {
// 如果是第一项,则直接插入
// 后一项不等于前一项,则插入后一项内容
newArr.push(value);
}
});
if (isN) newArr.push(NaN);
return newArr;
}
以上方法都进行过实际测试,测试的内容如下,返回结果除元素顺序不一致外,其他雷同。
delRepetition([
1, '1', 2, null, null, undefined, undefined,
'undefined', NaN, , NaN, 'NaN', 'null', 'true',
true, true, false, , false, 'false', ' ', '' ]);
// => [1, "1", 2, null, undefined, "undefined", NaN, "NaN", "null", "true", true, false, "false", " ", ""]
var set1 = new Set([1,1,1,2,2,3,4])
var a = [1,1,1,2,2,3,4]
function uniqByKey(arr){
let obj = {}
arr.forEach(item=>obj[item] = item)
return Object.values(obj)
}
console.log(uniqByKey(a))
var a = [1,1,1,2,2,3,4]
function uniqByTraversing(arr){
let result = []
arr.forEach(item => {
if(result.indexOf(item) <= 0) {
result.push(item)
}
})
return result
}
console.log(uniqByKey(a))
1、使用Set()方法
function myArray(array){ return new Set(array) }; var arrnum = [1,1,2,6,7,3,3,6,4,7]; myArray(arrnum);
2、普通方法去重
function myArray(arr){ var newArray = []; for(var i = 0;i <arr.length;i++){ if(newArray.indexOf(arr[i]) == -1){ newArray.push(arr[i]); } } return newArray; } var array = [1,1,2,3,5,6,4,3,2]; myArray(array);
1.使用set()方法
var arrList = [1,2,3,4,5,6,1,2]
function setArr(arr){
return new Set(arr)
}
console.log(setArr(arrList))
var arrlist =[1,2,3,4,5,6,1,2]
function removeSameNum(arr){
var newArr = []
for(var i=0;i<arr.length;i++){
if(newArr.indexOf(arr[i])===-1){
newArr.push(arr[i])
}
}
return newArr
}
console.log(removeSameNum(arrList))
遍历对象去重(参照上面大佬)
思路 声明空对象 遍历数组 利用Object.keys(赋值) 重复的会覆盖 最后object.values() 取得数组值
var list = [1,2,3,4,5,6];
function uniqueKey(arr){
let obj={}
arr.foreach(item=>obj[item] = item)
return Object.values(obj)
}
console.log(uniqueKey(list))
采用集合的方式
var a = [1, 2, 1, 3, 2]
var b = new Set(a) // Set(3){1,2,3}
var c = Array.from(b)// [1, 2, 3]
但当数组元素是引用类型的时候,则无法去重
数组双重循环去重
var arr = [1,2,3,4]
var result = []
for (var i = 0;i < arr.length; i++) {
for (var j = 0; j < result.length; j++) {
if (j !== 0 || result[j] === arr[i]) {
break
}
}
if (j == result.length) {
result.push(arr[i])
}
}
排序后比对
// 方法一 function unique1(arr) { return [...new Set(arr)] }
// 方法二 function unique2(arr) { var arr1 = [] for(var i = 0; i < arr.length; i++){ if(arr1.indexOf(arr[i]) == -1){ arr1.push(arr[i]) } } return arr1 }
// 方法三 function unique3(arr) { var arr1 = [] for(var i = 0; i < arr.length; i++){ if(!arr1.includes(arr[i])){ arr1.push(arr[i]) } } return arr1 }
// 方法四
function unique4(arr) { var arr1 = [] arr.sort(function(a,b){ return a-b })
for(var i = 0; i < arr.length; i++){ if(arr[i] !== arr[i+1]){ arr1.push(arr[i]) } }
return arr1 }
1.es6 的 set
;
Array.from(new Set(arr))
2.利用 includes
;
arr = [1,2,3,4,4,3,2,1]
let result = [];
for(const item of arr){
if(!result.includes(item)){
result.push(item);
}
}
indexOf
和 sort
。
arr.sort((a,b)=>a-b);
let result =[];
for(const item of arr){
if(result.indexOf(item)===-1){
result.push(item);
}
}
var arr = [1,2,3,4,4,5,6,3,3,1]
[...new Set(arr)] // [1, 2, 3, 4, 5, 6]
var arr = [1,2,3,4,4,5,6,3,3,1]
var newArr = arr.filter( (item, index, arr) => {
return index === arr.indexOf(item)
}) // [1, 2, 3, 4, 5, 6]
根据对象的key不重复的特性来实现
var arr = [1,2,3,4,4,5,6,3,3,1]
var o = {}
arr.forEach(e => o[e] = 1) // 随意赋值一个
var newArr = Object.keys(o).map(Number) // [1, 2, 3, 4, 5, 6]
var arr = [1,2,3,4,4,5,6,3,3,1]
var s = [];
//遍历数组
for(var i = 0;i<arr.length;i++){
if(s.indexOf(arr[i]) == -1){ //判断在s数组中是否存在,不存在则push到s数组中
s.push(arr[i]);
}
}
console.log(s) // [1, 2, 3, 4, 5, 6]
大方向啊,先考虑非嵌套数组去重。
然后拓展题, 尝试一下先写测试的函数:
const test = (fn, arg, result) => {
// 绝对是一个新的思路呢
}
// 解:
// em....我们可以使用, ES6的set
const unit1 = arr => {
return new Set(arr);
}
unit1([1, 2, 3, 1]);
//em....reduce.
const unit2 = arr => {
return arr.reduce((result, item) => {
result.includes(item) ? result : result.push(item);
return result;
}, [])
}
unit2([1, 2, 3, 1, NaN, NaN, -0, 0, +0, null, null]);
// em....map, 感觉和reduce一样一样的, 不写了。
// em....for.
const unit3 = arr => {
const result = []
arr.map(item => {
result.includes(item) ? void 0: result.push(item);
});
return result;
}
unit3([1, 2, 3, 1, NaN, NaN, -0, 0, +0, null, null]);
// em...对象的key值不能重复可以利用一下.
const unit4 = arr => {
let result = [];
let obj = {};
arr.map(item => {
obj[item] = null;
})
for(i in obj) {
result.push(i)
}
return result;
}
unit4([1, 2, 3, 1, NaN, NaN, -0, 0, +0, null, null]);
往深的看,嵌套数组去重.往深了走.
包含数组
包含对象
那么子问题是, 如何判断一个对象是不是相同.
数组其实就递归使用上面的方法就好呀.
但是再往深的看,其实这里如果自己写判断相等的函数还是涉及到一些坑, 比如类型。js的类型判断有几个坑, 比如-0, NaN, 所以我墙裂推荐大家使用数组的includes方法,它本身的实现已经考虑到js变态的类型机制了。当然你完全可以自己写判断两个元素是否相等的函数, 这绝对没问题.
额, 看来大家的答案, 有实现很酷的算法。好羡慕大佬啊, 算法还有算法导论都是好书,垫桌子真的很棒...
遍历需要去重的数组,如果当前数组的某个元素是第一次出现,则存入新的数组,否则忽略掉。
let unique = function (arr) {
let temp = []
arr.forEach((item, index) => {
if (temp.indexOf(item) === -1) {
temp.push(item)
}
})
return temp
}
let unique = function (arr) {
return [...new Set(arr)]
}
let unique = function (arr) {
let obj = {}
arr.forEach(item => obj[item] = item)
return Object.keys(obj) // 这里会导致类型被转换(原本是number型的,转成了string类型)
}
let unique = function (arr) {
const map = new Map()
return arr.filter(item => !map.has(item) && map.set(item, 1))
}
Set
Set
类似于数组,但是成员的值都是唯一的,没有重复的值。
function uniq(arry) {
return [...new Set(arry)];
}
indexOf
function uniq(arry) {
var result = [];
for (var i = 0; i < arry.length; i++) {
if (result.indexOf(arry[i]) === -1) {
//如 result 中没有 arry[i],则添加到数组中
result.push(arry[i])
}
}
return result;
}
includes
function uniq(arry) {
var result = [];
for (var i = 0; i < arry.length; i++) {
if (!result.includes(arry[i])) {
//如 result 中没有 arry[i],则添加到数组中
result.push(arry[i])
}
}
return result;
}
reduce
function uniq(arry) {
return arry.reduce((prev, cur) => prev.includes(cur) ? prev : [...prev, cur], []);
}
Map
function uniq(arry) {
let map = new Map();
let result = new Array();
for (let i = 0; i < arry.length; i++) {
if (map.has(arry[i])) {
map.set(arry[i], true);
} else {
map.set(arry[i], false);
result.push(arry[i]);
}
}
return result;
}
const Arr = [1,2,3,4,5,5,5,8,7,4,1,2,3,6,10,10,10,'10','10'];
const uniqueArr = Arr.sort((a,b) => a - b ).filter((e,i,a) => a[i] !== a[i - 1]);
console.log(uniqueArr );
const Arr = [1,2,3,4,5,5,5,8,7,4,1,2,3,6,10,10,10,'10','10'];
const uniqueArr = Array.from(new Set(Arr));
console.log(uniqueArr );
var arr = [1,1,1,2,1,2,1,'1','2']
arr = [...new Set(arr)]
const arr = [1,1,1,2,1,2,1,'1','2']
let removerepeat = function(nums) {
nums = nums.filter((val, index) => {
return index == nums.indexOf(val);
});
return nums;
};
removerepeat (arr)
3.map去重
let remove2 = function(nums) {
let map = new Map();
nums.forEach(item => {
map.set(item, "");
});
return map.keys();
};
remove2([1, 61, 161, 7, 7, 7, 1, 3, "2", "2"]);
function removeDuplicates(arr) {
return Array.from(new Set(arr));
}
空间复杂度: O(n) 时间复杂度: O(n)
function removeDuplicates(arr) {
arr.sort(function(a, b) {
return a - b;
});
let i = 0;
let j = 1;
while (j < arr.length) {
if (arr[j] !== arr[i]) {
i++;
arr[i] = arr[j];
}
j++;
}
arr.splice(i + 1);
return arr;
}
时间复杂度: O(nlogn) 空间复杂度: O(1)
方式一 Set去重
function unique (arr) {
//return [...new Set(arr)];
return Array.from(new Set(arr));
}
方式二 indexOf
function unique (arr) {
const temp = [];
for (let i = 0; i < arr.length; i++) {
if (temp.indexOf(arr[i]) == -1) {
temp.push(arr[i]);
}
}
return temp;
}
方式三 先排序在去重
function unique (array) {
array.sort();
const temp = [];
for (let i = 0; i < array.length; i++) {
if (array[i] !== array[i + 1]) {
temp.push(array[i]);
}
}
return temp;
}
方式四 利用filter和includes
function unique (arr) {
let temp = [];
temp = arr.filter(element => {
return temp.includes(element) ? '' : temp.push(element);
});
return temp;
}
方式五 利用对象属性方法
function unique (array) {
let object = {};
let temp = [];
array.forEach(element => {
if (!object[element]) {
object[element] = 1;
temp.push(element);
}
});
return temp;
}
简单的数组去重
// 利用Set对象
let arr = [1,2,3,4,5,5,6,null,null,undefined];
console.log(...new Set(arr));
// 利用Map对象
function unique(arr) {
const arrMap = new Map();
return arr.filter(item=> !arrMap.has(item) && arrMap.set(item,1))
}
let arr = [1,2,3,4,5,5,6,null,null,undefined];
console.log(unique(arr));
// 利用indexof
function unique(arr) {
let uniqueArr = [];
arr.forEach((item,index) =>{
if(uniqueArr.indexOf(item) === -1){
uniqueArr.push(item);
}
})
return uniqueArr;
}
let arr = [1,2,3,4,5,5,6,null,null,undefined];
console.log(unique(arr));
// 利用reduce(这种写法还是第一次见,长见识了)
function unique(arry) {
return arry.reduce((prev, cur) => prev.includes(cur) ? prev : [...prev, cur], []);
}
let arr = [1,2,3,4,5,5,6,null,null,undefined];
console.log(unique(arr));
数组对象去重
function unique(arr, key) {
const map = new Map()
return arr.filter((item) => !map.has(item[key] + '') && map.set(item[key] + '', 1))
}
let arr = [
{ name: 'a', num: 1},
{ name: 'b', num: 1},
{ name: 'c', num: 1},
{ name: 'd', num: 1},
{ name: 'a', num: 1},
{ name: 'a', num: 1},
{ name: 'a', num: 1}
]
console.log(unique(arr));
1.new Set(简单粗暴)
function DeWeighting(array){ return [...new Set(array)] }
2.indexOf
function DeWeighting(array){ let temp = [] array.forEach(element => { if(temp.indexOf(element) == -1){ temp.push(element) } }); return temp }
3.includes
function DeWeighting(array){ let temp = [] array.forEach(element => { if(!temp.includes(element)){ temp.push(element) } }); return temp }
1、ES6中新增了数据类型set,set的一个最大的特点就是数据不重复。Set函数可以接受一个数组(或类数组对象)作为参数来初始化,利用该特性也能做到给数组去重。 function unique(arr) {
} 2、数组的indexOf()方法可返回某个指定的元素在数组中首次出现的位置。该方法首先定义一个空数组res,然后调用indexOf方法对原来的数组进行遍历判断,如果元素不在res中,则将其push进res中,最后将res返回即可获得去重的数组。 function unique(arr) {
} 3、创建空对象,遍历数组,将数组中的值设为对象的属性,并给该属性赋初始值1,每出现一次,对应的属性值增加1,这样,属性值对应的就是该元素出现的次数了。 function unique(arr) {
}