• 数组扁平化的几种处理放法


    清明节,这几天放假闲来无事,好好研究一下基础知识,今天看看数组扁平化该怎么处理:

    先来看数组扁平化是什么:

    var arr = [1,2,3,4,[5,6,[7,8]],true] =>
        	[1,2,3,4,5,6,7,8,true]

    就是把二维或者多维数组,转成一维数组。

    1、我想大部分同学会和一样,首先想到的肯定是遍历数组,如果某一项是基本数据类型,直接push到新数组,如果某一项是数组,则直接将这一项concat到新的数组上,当然如果是多维数组,还得用上递归的方法,继续往下层寻找,上代码:

    function flatten(arr) {
    	var result = []
    	for (var i = 0; i < arr.length; i++) {
    		console.log(arr[i])
    		if (Array.isArray(arr[i])) {
    			result = result.concat(flatten(arr[i])) // 如果是数组,则直接拼接到新数组
    		} else {
    			result.push(arr[i]) // 基本类型数据,直接push到新数组
    		}
    	}
    	return result
    }
    console.log(arr, flatten(arr)) //  [1, 2, 3, 4, Array(3), true] [1, 2, 3, 4, 5, 6, 7, 8, true]

      我们看看结果,已经得到我们想要的结果了,且原数组没变化。

    2、第二种方法:使用 数组的reduce(fn(), init, index, arr)+concat()方法
    a.遍历每一项,并按fn()中规则处理每一项: 如果是基本类型,暴力concat到要返回的数组中,如果是数组则拼接到返回的数组上,如果是多维数组,递归调用;
    b.init是要返回结果的初始值;
    c第三和四参数可省略。

    function flatten(arr) {
    	return arr.reduce((result, item) => {
    		return result.concat(Array.isArray(item) ? flatten(item) : item)
    	}, [])
    }
    console.log(arr, flatten(arr)) //  [1, 2, 3, 4, Array(3), true]       [1, 2, 3, 4, 5, 6, 7, 8, true]

      我们看看结果,也得到我们想要的结果了,且原数组没变化。

    3、第三种方法: 使用while循环some条件和apply特性,我们知道apply(obj, [ ])
    a.第一个参数,是要调用已存在方法的对象,例如c.apply(d, []) ,d就继承了c的特性,这个参数和这篇文章没有太大关系,可以先不理解;

    b.第二个参数是指的,要处理的数据,且一定是一个值,可以是数组或其他值,但必须是一个,如果是一个数组,那么会一次处理数组中的元素。好,这里就是利用这个特性,一次处理数组中的每一项,当然包括二级和多级数组:

    function flatten(arr) {
    	while (arr.some(item => Array.isArray(item))) { // 只要arr中某一项还是数组,则一直执行下去,直到全转成基本类型数据
    		arr = [].concat.apply([], arr) // 这里第二个新[]继承了concat方法,所以能对arr中的元素逐一concat到第二个新[]中。
    	}
    	return arr
    }
    console.log(arr, flatten(arr)) //  [1, 2, 3, 4, Array(3), true]       [1, 2, 3, 4, 5, 6, 7, 8, true]
    // 第一遍执行返回: [1,2,3,4,[5,6,[7,8]],true] => [1,2,3,4,5,6,[7,8],true],我们看到只处理了第二层数组[5,6,[7,8]],
    // 把这个数组当成一项直接concat到新数组,第三层[7,8]没有处理,但第三层已经变成了第二层,再处理一次即可
    // 第二遍执行返回:   [1,2,3,4,5,6,[7,8],true] =>  [1,2,3,4,5,6,7,8,true] 得到我们先要的结果


    // 如果还有第四层或更多,while循环会一直执行下去,直到变成一维数组。

    4、使用ES6中展开运算符...和while循环,方法3你能理解的话,这个就很好理解了,我不管了,上代码,自己分析:

    function flatten(arr){
      while (arr.some(item => Array.isArray(item))){
        arr = [].concat(...arr); // 如果你明白展开运算符的作用,是不是很简单?
      }
      return arr;
    }
    

    5、困难重重的数组扁平化的方法你掌握的差不多了,到了放大招的时候了,ES6总是能让人出其不意攻其不备,来看看杀手锏-flat(depth) 方法会按照一个可指定的深度(depth可以为任意正整数,和Infinity - 任意深度默认为1)递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

    var arr= [1,2,3,4,[5,6,[7,8]],true]
    arr.flat()
    // [1, 2, 3, 4, 5, 6, Array(2), true]
    var arr= [1,2,3,4,[5,6,[7,8]],true]
    arr.flat(Infinity)
    // [1, 2, 3, 4, 5, 6, 7, 8, true]

    好了,今天主要分析了二维和多维数组降到一维的几种方法,当然还有其他方法,如果数组中全是数字的话,也可以使用toString()或者join()结合split(),先转成字符串,再转成数组的方法:

    var arr = [1,2,3,4,[5,6,[7,8]]]
    function flatten(arr) {
    	return arr.toString().split(',').map(item => {
    		return item - 0 // 字符转数字: item - 0 , + item  , item * 1 , item / 1都能实现 
    	})
    } 
    console.log(flatten(arr)) // [1,2,3,4,5,6,7,8]

    以上是我对数组扁平化处理方法的理解while遍历有两种,分别是apply和ES6展开运算符操作,for循环结合递归一种,reduce()遍历一种,杀手锏flat()一种。说来说去还是离不开遍历,现在清楚多了,如果你有好的想法,欢迎分享出来。

  • 相关阅读:
    第三部分:填写志愿的思路
    第二部分:志愿录取标准
    2017年浙江省高考志愿、录取闪电入门系列 目录
    七、程序包
    五、过程式编程和调试技巧
    四、表达式的计算
    三、函数与递归
    二、表操作
    一、MMA概述
    Java面向对象
  • 原文地址:https://www.cnblogs.com/whq920729/p/10662031.html
Copyright © 2020-2023  润新知