相關(guān)學(xué)習(xí)推薦:javascript視頻教程
前言
從去年發(fā)現(xiàn)字符串的replace方法有很多神奇用法的時候,就想做這個系列,但是一直沒空,也沒有想到很好的名字,就擱置了。上周五刷題的時候看評論有個解決方法是用Array.from一行解決,而且效率還挺高的。于是啃了一下文檔和博客,搞清楚了之后就想正好可以開始這個系列了。而且數(shù)組是我們開發(fā)中最常用的數(shù)據(jù)結(jié)構(gòu)之一,作為生成數(shù)組的方法之一,以from開始也蠻意思。系列名字就先湊合這么叫吧。
- 基礎(chǔ)語法
定義:from() 方法用于通過擁有 length 屬性的對象或可迭代的對象來返回一個數(shù)組。
語法:Array.from(object, mapFunction, thisValue)
參數(shù) | 描述 |
object |
必需,要轉(zhuǎn)換為數(shù)組的對象。 |
mapFunction |
可選,數(shù)組中每個元素要調(diào)用的函數(shù)。 |
thisValue |
可選,映射函數(shù)(mapFunction)中的 this 對象。 |
- 示例用法
1. 將類數(shù)組轉(zhuǎn)化為數(shù)組
Array.from('hello') //["h", "e", "l", "l", "o"] Array.from(new Set(['name','age'])) //["name", "age"] Array.from({name:'lgc',age:25}) //[] let map=new Map() map.set('name','lgc') map.set('age',25) Array.from(map) //[["name", "lgc"],["age", 25]] function test(){ console.log(Array.from(arguments)) } test(1,2,3) //[1, 2, 3]復(fù)制代碼
這是我們平時最常用的功能,寫這些示例的時候我還奇怪:為什么map能轉(zhuǎn)成數(shù)組而object只能轉(zhuǎn)為空數(shù)組。當(dāng)我查看菜鳥教程,看到上述定義我才明白。object既沒有l(wèi)ength也不是可迭代對象,我之前以為object也是可迭代對象,畢竟都可以用for-in嘛。但其實es6的object不是可迭代對象,這里不多贅述,有興趣的同學(xué)可以去查一下。
2. 數(shù)組深拷貝(一行代碼)
function clone(arr){ return Array.isArray(arr) ? Array.from(arr, clone):arr } let arrayA=[[1,2],[3,4]] let arrayB=clone(arrayA) arrayA===arrayB //false arrayA[0]===arrayB[0] //false復(fù)制代碼
這里主要用到了Array.from的第二個參數(shù)mapFunction,mapFunction默認(rèn)傳兩個參數(shù),數(shù)組的值和下標(biāo)。
3. 數(shù)組去重
function unique(arr){ return Array.from(new Set(arr)) }復(fù)制代碼
這也是from最基本,也是我們最常用的功能之一。
4. from的其他用法
再看一遍from定義:from() 方法用于通過擁有 length 屬性的對象或可迭代的對象來返回一個數(shù)組。擁有l(wèi)ength就行?試一試
Array.from({length:2},(val,index)=>index) //[0,1]復(fù)制代碼
可以,那他有什么用呢?第一,像上面代碼,可以很方便生成在一定范圍,有一定規(guī)則的數(shù)組
Array.from({length:3},(val,index)=>index*10) //[0,10,20]復(fù)制代碼
第二,數(shù)組的初始化。比如你想生成指定長度的對象數(shù)組。第一反應(yīng)是什么?fill嗎?
let testArr=Array(3).fill({}) testArr[0]===testArr[1] //true復(fù)制代碼
這里的每個對象其實都是同一個,你修改一個其他自然會跟著改變,但很多時候我們需要的并不是這樣的。
let testArrb=Array.from({length:3},()=>({})) testArrb[0]===testArrb[1] //false復(fù)制代碼
這兩個方法可以根據(jù)需求使用。
5. from的進(jìn)階用法
上面的內(nèi)容其實層層遞進(jìn)下來都是為了更好的理解下面的解題思路。
LeetCode第867題:
給定一個矩陣 A
, 返回 A
的轉(zhuǎn)置矩陣。
矩陣的轉(zhuǎn)置是指將矩陣的主對角線翻轉(zhuǎn),交換矩陣的行索引與列索引。
示例 1: 輸入:[[1,2,3],[4,5,6],[7,8,9]] 輸出:[[1,4,7],[2,5,8],[3,6,9]] 示例 2: 輸入:[[1,2,3],[4,5,6]] 輸出:[[1,4],[2,5],[3,6]]
當(dāng)時第一反應(yīng)這就不是索引互換嗎?賊簡單。于是寫了如下代碼
var transpose = function(A) { let x=A.length let y=A[0].length for(let i=0;i<x;i++){ for(let j=0;j<y;j++){ if(j-i>0){ [A[i][j],A[j][i]]=[A[j][i],A[i][j]] } } } return A };復(fù)制代碼
執(zhí)行代碼:通過,提交:失敗。臥槽?看一下錯誤提示,發(fā)現(xiàn)忽略了示例2這種,“長寬”不等的情況。轉(zhuǎn)換思路,內(nèi)外循環(huán)翻轉(zhuǎn)。最外循環(huán)每執(zhí)行一次即一列當(dāng)做行。執(zhí)行,通過。
不過這版看起來太撈了,而且執(zhí)行時間太慢。但畢竟自己實現(xiàn)了,可以去評論區(qū)找一下其他思路。
下面這個就是看評論區(qū)大神實現(xiàn),第一次都沒看懂。
var transpose = function(A) { return Array.from({length:A[0].length},(_v,i)=>A.map(v=>v[i]))};復(fù)制代碼
{length:A[0].length},是以給定矩陣的寬作為轉(zhuǎn)置矩陣的長,為了滿足“擁有 length 屬性的對象”這一條件。(_v,i)=>A.map(v=>v[i]),取給定矩陣的列作為轉(zhuǎn)置矩陣的行。核心思路和我第二版是一樣的,但是實現(xiàn)方式和技巧就秀太多了。而且執(zhí)行時間也較短,膜拜大神。
想了解