JS中的数组常用方法和数组去重

数组常用方法

  • 添加/删除元素:

    • push(…items): 从结尾添加元素,并返回新的长度
    • pop( ): 用于删除数组的最后一个元素,并返回删除的元素
    • shift( ): 从开头删除元素,并返回第一个元素的值
    • unshift(…items):从开头添加元素,并返回新的长度
    • splice(pos,deleteCount,…items):从index开始删除,删除deleteCount元素,并在当前位置插入一个或者多个元素,如果只是删除了元素,则返回的是含有被删除的元素的数组,否则为空
    • slice(start,end):它从索引“start”复制到“end”(不包括“end”)返回一个新的数组
    • concat(…items):返回一个新数组:复制当前数组的所有成员并向所有成员中添加items,如果有任何items是一个数组,那么久取其全部元素
  • 查询元素:

    • indexOf(item,pos):从pos位置开始检索item,有就返回索引否则返回-1;如果没有设置pos则默认从0开始
    • lastIndexOf(item,pos):从pos位置开始检索item,有就返回索引否则返回-1;如果没有设置pos则默认从length-1开始
    • includes(value):如果数组有value,则返回true,否则返回false
    • find/filter(func):通过函数过滤元素,返回符合find函数的第一个值或者符合filter函数的全部值
    • findIndex(func):和find类似,但是它返回索引而不是值
  • 转换数组:

    • map(func): 从每个元素调用func的结果并返回一个新数组
    • sort(func): 将数组排序,如何从小到大,func((a,b) => a-b),否则b-a,原地修改数组,并返回修改后的新数组
    • reserve():在原地颠倒数组,然后返回它
    • split/join:前者将字符串转换为数组,后者将数组转换为字符串,并返回
    • reduce(func,initial):一般用于求和,通过为每个元素调用func计算数组上的单个值并在调用之间传递中间结果
  • 迭代元素

    • forEach(func): 为每个元素调用func,不返回任何东西
  • 其他

    • Array.isArray(arr): 检查arr是否是一个数组
    • arr.some(fn)/arr.every(fn): 在类似于map的数组的每个元素上调用函数fn。如果任何/所有结果为true,则返回true,否则返回false。常用于检查元素
    • arr.fill(value,start,end): 从start到end用value 重复填充数组
    • arr.copyWithin(target,start,end):将在tartget位置索引开始,从start到end复制到本身例如:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.copyWithin(2, 0);
// fruits
Banana,Orange,Banana,Orange

数组去重

1.ES6 Set去重

function unique (arr) {
  return [...new Set(arr)] // Array.from(new Set(arr))
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
 //[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]

不考虑兼容性,这种去重的方法代码最少。这种方法还无法去掉“{}”空对象,后面的高阶方法会添加去掉重复“{}”的方法。
为什么无法去掉"{}"对象呢?
原因在于set方法比较时会比较key和value,前者使用hashCode() 后者使用equals()方法,如果set对象不手动使用equals()和hashCode(),key值是不同的,所以无法识别去重

2.利用for嵌套for,然后splice去重(ES5中最常用)

双层循环,外层循环元素,内层循环时比较值。值相同时,则删去这个值。

function unique(arr){            
        for(var i=0; i<arr.length; i++){
            for(var j=i+1; j<arr.length; j++){
                if(arr[i]===arr[j]){         //第一个等同于第二个,splice方法删除第二个
                    arr.splice(j,1);
                    j--;
                }
            }
        }
return arr;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
    console.log(unique(arr));
    //[1,'true',true, 15,false, undefined,null,NaN,NaN,'NaN',0,'a',{},{}];
    //NaN和{}没有去重

NaN和{}没有去重
为什么 NaN === NaN 为false
NaN的意思是Not a Number,那么不是数字的字符肯定不是一个,而是一个范围,一个集合。就好像A不是数字,B也不是数字,但是A肯定不是B一样。所以综上NaN其实是不等于它自身的。
为什么 {} === {} 为false
当比较两个object大小时,会调用object的valueOf方法,如果结果能直接比较,则返回比较结果;如果结果不能直接比较大小,则会调用object的toString方法,并返回比较结果

3.利用indexOf去重

新建一个空的结果数组,for循环原数组,判断结果数组是否存在当前元素,如果有相同的值则跳过,不相同则push进数组。

var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];

function unique(arr) {
  let newArr = [];
  for (let i = 0; i < arr.length; i++) {
    if(newArr.indexOf(arr[i]) === -1) {
      newArr.push(arr[i])
    }
  }
  return newArr
}
console.log(unique(arr));
// [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}] 
// NaN、{}没有去重

4.sort()

function unique(arr) {
    arr = arr.sort()
    var arrry= [arr[0]];
    for (var i = 1; i < arr.length; i++) {
        if (arr[i] !== arr[i-1]) {
            arrry.push(arr[i]);
        }
    }
    return arrry;
}
     var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
    console.log(unique(arr))
// [0, 1, 15, "NaN", NaN, NaN, {…}, {…}, "a", false, null, true, "true", undefined]  
// NaN、{}没有去重    

5.includes

function unique(arr) {
    var array =[];
    for(var i = 0; i < arr.length; i++) {
            if( !array.includes( arr[i]) ) {//includes 检测数组是否有某个值
                    array.push(arr[i]);
              }
    }
    return array
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
    console.log(unique(arr))
    //[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]   
    //{}没有去重

6.hasOwnProperty

obj.hasOwnProperty(prop) hasOwnProperty( )方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)
参数
prop:要检测的属性的 String 字符串形式表示的名称,或者 Symbol。
返回值
用来判断某个对象是否含有指定的属性的布尔值 Boolean。

即使属性的值是 null 或 undefined,只要属性存在,hasOwnProperty 依旧会返回 true。

利用hasOwnProperty 判断是否存在对象属性

function unique(arr) {
  var obj = {}
  return arr.filter(function(item,index,arr){
    return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
  })
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr));
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}]
//所有的都去重了

7.filter

function unique(arr) {
  return arr.filter(function(item,index,arr){
    return arr.indexOf(item) === index;
  })
}

var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr));
//[1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {}, {}]
//{}没有去重

8.reduce+includes

function unique(arr) {
  return arr.reduce((pre,cur) => pre.includes(cur) ? pre : [...pre,cur],[])
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr));
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]

你可能感兴趣的:(JS中的数组常用方法和数组去重)