數組扁平化的幾種處理放法


清明節,這幾天放假閑來無事,好好研究一下基礎知識,今天看看數組扁平化該怎么處理:

先來看數組扁平化是什么:

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()一種。說來說去還是離不開遍歷,現在清楚多了,如果你有好的想法,歡迎分享出來。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM