JavaScript | 数组常用的"奇淫技巧"

903 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情

一、前言

数组在平时开发用的可太多了,数组方法结合处理数据可以无所不能,这里归纳了一些常用的技巧。

二、数组扁平化

1. 使用数组原型中的falt方法

  • flat基本用法:
    • arr.flat()
  • 参数说明
    • arr.flat() 默认不写参数则是扁平化一层,也就是只能扁平化二维数组
    • arr.flat(1/2/3...)参数写数字几则是扁平化几层
    • arr.flat(Infinity)Infinity则是不管是几维数组都可以直接扁平化
   let arr = [1, 2, 3, [4, 5, 6, [7, 8, [9, 10, 11]]]];
   arr.flat(Infinity) //[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

2. 使用toString.split()

主要用于把数字转为字符串

    let arr = [1, 2, [3, 4, [5, 6, [7, 8, 9]]]];
    arr.toString().split(',') //['1', '2', '3', '4', '5', '6', '7', '8', '9']

3. 三点运算符 ... + some() + concat()

主要是利用some判断是否为数组,满足返回true,利用[].concat(...arr)去展开拼接

    let arr = [1, 2, 3, [4, 5, 6, [7, 8, [9, 10, 11]]]];
    function flatten(arr) {
        while (arr.some(item => Array.isArray(item))) {
            arr = [].concat(...arr);
        }
        return arr;
   }
   flatten(arr) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

4. 递归for循环扁平化

   let arr = [1, 2, 3, [4, 5, 6, [7, 8, [9, 10, 11]]]]
    function flat(arr){
      let list = []
      for(let i = 0;i<=arr.length;i++){
         if(typeof arr[i] == 'number'){
           list.push(arr[i])
         }else if(Array.isArray(arr[i])){
           flat(arr[i])
           list.push(...flat(arr[i]))
         }

      }
      return list
    }
    let re = flat(arr)
    console.log(re) //[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

三、数组去重

1. 双重循环

在还没接触数组方法时候的一个简单方法,缺点是代码冗余,如果数组长度比较长,双循环的写法,内存消耗会比较大。

    let arr = [1,1,2,2,3,3,4,4,5,5]
    let newArr = [];
    let flag = true;
    for(let i = 0; i < arr.length; i++){
        //外部循环取数
        for(let j = 0; j < newArr.length; j++){
            //内层循环是为了和外层取的数取对比,看新数组当中是否有
            if(arr[i] == newArr[j]){
                flag = false;
                break;
            }
        }

        if(flag){
            newArr[newArr.length] = arr[i];
        }
        flag = true;
    }
    console.log(newArr) //[1, 2, 3, 4, 5]

2. indexOf

indexOf()方法的主要特性是返回某个指定的元素在数组中首次出现的位置,新建一个数组用来保存每一次遍历的结果,再判断遍历的数组进行首次出现的比对来实现去重。

    let arr = [1,1,2,2,3,3,4,4,5,5]
    function removeRepeat(array) {
        let res = [];
        for (let i = 0, len = array.length; i < len; i++) {
            let current = array[i];
            if (res.indexOf(current) === -1) {
                res.push(current)
            }
        }
        return res;
}
removeRepeat(arr) //[1, 2, 3, 4, 5]

3. filter

filter过滤就是indexOf去重的的改良版,直接返回过滤首次出现的元素达到过滤.

   let arr = [1,1,2,2,3,3,4,4,5,5]
    function removeRepeat(array) {
        let res = array.filter(function(item, index){
            return array.indexOf(item) === index;
        })
        return res;
}
removeRepeat(arr) //[1, 2, 3, 4, 5]

4. Object 键值对

    let arr = [1, 2, 1, 1, '1'];
    function removeRepeat(array) {
        let obj = {};
        return array.filter(function(item, index, array){
            return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)	// 因为1 和 '1' 是不同的,所以使用typeof item + item 拼成字符串作为 key 值
        })
    }
    removeRepeat(arr) //[1, 2, '1']

5. set方法

ES6中新增了数据类型set,set的一个最大的特点就是数据不重复。Set函数可以接受一个数组(或类数组对象)作为参数来初始化,利用该特性也能做到给数组去重

    let arr = [1, 2, 1, 1, '1'];
    function removeRepeat(array) {
     return [...new Set(array)];
   }
   removeRepeat(arr) //[1, 2, '1']

四、万物皆可reduce

可以用reduce来完成很多场景的需求

1. reduce求数组的最大值/最小值

    let arr = [1,2,3,4,5,6]
    let result = arr.reduce( (p, c) => {
        return p > c ? p : c
    })
    console.log(result) //6
    
    let result = arr.reduce( (p, c) => {
        return p > c ? c : p
    })
    console.log(result) //1

2. 计算字符串中每一个值出现的次数,用对象来表示

    let str = "abcdaedfbcdba"
    let result = [...str].reduce(function (p, c) {
        p[c] ? p[c]++ : p[c] = 1
        return p
    }, {})
    console.log(result) //{a: 3, b: 3, c: 2, d: 3, e: 1, e:1}

3. 数组去重

    let arr = [1, 3, 3, 2, 1, 1, 4, 5, 3, 4, 7, 6, 5, 7]
    let result = arr.reduce(function (p, c) {
         if (p.includes(c)) {
             return p
         }
         return [...p, c]
     }, [])
     console.log(result) //[1, 3, 2, 4, 5, 7, 6]

4. 数组扁平化

    let arr = [[1, 2],[3, 4], [5, [6]]]
     function flat(arr) {
        if (!Array.isArray(arr)) {
            return arr
        }
        return arr.reduce(function (p, c) {
            return p.concat(flat(c))
        }, [])
    }
    console.log(flat(arr)) //[1, 2, 3, 4, 5, 6]

5. 数组的单向对比

      let arr1 = [1, 2, 3, 4, 5, 6, 7]
      let arr2 = [2, 3, 5, 6]
      
       function fn(arr1 = [], arr2 = []) {
        const re = arr1.reduce(function (p, c) {
            arr2.includes(c) || p.push(c)
            return p
        }, [])
        console.log(re)
    }
    fn(arr1, arr2) // [1, 4, 7]

6. 翻转字符串

   let str = 'lucky'
   let reserveStr = ((item)=>{
     return str.split("").reduceRight((t, v) => t + v)
  })
  console.log(reserveStr(str)) //ykcul

五、查找两个数组中的重复项

    let arr1 = [1, 2, 3, 4, 5, 6, 7]
    let arr2 = [2, 3, 5, 6]
    
   function fn(arr1, arr2) {
    return arr1.filter(n => arr2.indexOf(n) != -1);
 }
   fn(arr1,arr2) //[2, 3, 5, 6]

好了,以上就是本篇文章的分享,感谢阅读!