這是一個難題!
數(shù)組之?dāng)?shù)組,顧名思義,就是一個數(shù)組的元素是另外一個數(shù)組。很多現(xiàn)實(shí)問題,本來有巧妙地解法,但是因?yàn)镋xcel不支持?jǐn)?shù)組之?dāng)?shù)組,導(dǎo)致這些問題根本解決不了。
其實(shí),Excel本身是可以進(jìn)行這樣的計(jì)算的,只不過需要另外的技巧。這里我們介紹一個非常特殊的公式,利用這個公式,可以解決數(shù)組之?dāng)?shù)組的難題
下圖展示了什么是數(shù)組之?dāng)?shù)組:
公式1,查找的結(jié)果是一個值"a"。
公式2,返回A,B兩列,所以查找值變成了一個數(shù)組{1, "a"}。
公式3,由于查找條件成為一個數(shù)組,{1;2},所以返回結(jié)果也是一個數(shù)組:{"a"; "b"}。
來到公式4, 這里條件是一個數(shù)組,返回值是A,B兩列,所以,我們期望返回結(jié)果是一個兩行兩列的數(shù)組:{1, "a"; 2, "b"}。
我們期望的實(shí)際上就是數(shù)組之?dāng)?shù)組:因?yàn)橛袃蓚€條件,所以返回一個兩行的數(shù)組,因?yàn)榉祷貎闪校悦啃卸际且粋€1行兩列的數(shù)組。
但是,Excel不支持?jǐn)?shù)組之?dāng)?shù)組,我們只能得到第一列,即{1; 2}。
我們可以猜想,畢竟XLOOKUP函數(shù)是VLOOKUP函數(shù)的升級,它們的工作原理基本沒有變化,本身不能支持循環(huán)處理數(shù)組的元素。
但是,我們有一批新函數(shù):MAP,REDUCE,SCAN等等,這些函數(shù)可以進(jìn)行循環(huán),單獨(dú)處理其中的每個元素。既然如此,我們就可以從它們?nèi)胧终艺医鉀Q辦法。
先試試這個公式:
=MAP(D1:D3,LAMBDA(a,XLOOKUP(a,A1:A7,A1:B7)))
這個公式可以用下面的圖示說明:
MAP將條件數(shù)組映射成一個結(jié)果數(shù)組(3行),每一個元素映射規(guī)則是使用XLOOKUP進(jìn)行查找,返回一個1行兩列的數(shù)組。
但是這個函數(shù)失敗了:
失敗的原因還是“數(shù)組之?dāng)?shù)組”。
為了挽救我們的嘗試,我們需要一個神奇的公式:
= LAMBDA(x, LAMBDA(x))
這是一個嵌套的LAMBDA公式(詳情參見這里)。這個公式的工作原理見下圖:
輸入?yún)?shù)x后,該公式返回一個LAMBDA函數(shù),該函數(shù)沒有參數(shù),只是簡單地返回x。
用這個公式創(chuàng)建自定義函數(shù)后:
FUNC = LAMBDA(x, LAMBDA(X));
調(diào)用是這樣的:
=FUNC(A1)()
=FUNC(A1:B10)()
第一個括號里可以任意寫,可以是一個值,也可以是個數(shù)組,整個公式會返回第一個括號里的內(nèi)容。
不要忘了第二個括號。
這個自定義函數(shù)的作用是將x的值存放在一個未知的"位置"中,等待第二個括號時,將其返回!
現(xiàn)在我們進(jìn)行第二次嘗試:
=MAP(D1:D3, LAMBDA(a, FUNC(XLOOKUP(a,A1:A7,A1:B7))))
作為對照,我們看看第一次嘗試的公式:
=MAP(D1:D3,LAMBDA(a,XLOOKUP(a,A1:A7,A1:B7)))
這里,將每一次映射的XLOOKUP公式返回的結(jié)果放在FUNC函數(shù)的第一個括號里。
明白這個意思吧。
既然,數(shù)組的元素不能是數(shù)組,那么我們將其放在一個自定義函數(shù)里總可以吧,一個自定義函數(shù)作為數(shù)組的元素,這是允許的!
我們再看現(xiàn)在的返回值:
仍然是同樣的錯誤!
不過有一點(diǎn)區(qū)別,從一個錯誤變成了一個錯誤數(shù)組了!
這是進(jìn)步,表示計(jì)算了三行,MAP的功能實(shí)現(xiàn)了!
再看每個錯誤值:
錯誤解釋變成了“單元格包含LAMBDA”!
什么意思?
這個意思是說產(chǎn)生錯誤的這個單元格中有一個LAMBDA函數(shù)沒有參數(shù)。
曙光乍現(xiàn)。
現(xiàn)在很明白了,就是每個單元格代表一個LAMBDA函數(shù),但是這個LAMBDA函數(shù)沒有最后一個括號。
我們使用這個公式:
=INDEX(MAP(D1:D3, LAMBDA(a, FUNC(XLOOKUP(a, A1:A7, A1:B7)))), 2, 1)()
其中的MAP公式就是前面介紹的公式。但是,我們使用INDEX將其第二行,第一個元素取出。
這就是2這個條件,用XLOOKUP查找出的一行兩列數(shù)組。不過我們將它放在了FUNC函數(shù)中。但是這個FUNC函數(shù)返回的是一個LAMBDA公式,所以需要參數(shù)。因此,后面要加上一個()。
結(jié)果就是
這是我們期望的結(jié)果。
這說明,這個公式中每一個返回錯誤值的元素,實(shí)際上都可以用同樣的方法返回一個數(shù)組。
有了這個基礎(chǔ),返回?cái)?shù)組之?dāng)?shù)組就不在話下了。
甚至,我們可以做到其中的每個數(shù)組都是不同大小的。
假設(shè),我們需要將左邊的A1:A3做映射,其中將1,映射成1行,將2映射成兩行,將3映射成3行。
= SCAN(0,A30:A32,LAMBDA(acc,a,SEQUENCE(a,1)))
這里掃描原始數(shù)據(jù),每一個元素都映射成一個n行數(shù)組,n是原始數(shù)組中循環(huán)到的當(dāng)前元素值。
但是,我們知道,這個公式肯定會返回一個錯誤值。
所以,我們將它處理下:
=SCAN(0,A30:A32,LAMBDA(acc,a,FUNC(SEQUENCE(a,1))))
顯然,這個函數(shù)一定可以計(jì)算出每行的數(shù)組,只不過我們需要將它取出,并通過函數(shù)運(yùn)算釋放這個數(shù)組:
=INDEX(SCAN(0,A30:A32,LAMBDA(acc,a,FUNC(SEQUENCE(a,1)))),3,1)()
這個公式取出第三個元素映射成的數(shù)組,當(dāng)然是三行一列的數(shù)組:
詳細(xì)解釋請看視頻
加入E學(xué)會,永久免費(fèi)學(xué)習(xí)更多Excel應(yīng)用技巧
http://www.tropic.com.cn/portal/learn/class_list
Excel+Power Query+Power Pivot+Power BI
自定義函數(shù) 底部菜單:知識庫->自定義函數(shù)
面授培訓(xùn) 底部菜單:培訓(xùn)學(xué)習(xí)->面授培訓(xùn)
Excel企業(yè)應(yīng)用 底部菜單:企業(yè)應(yīng)用
也可以在歷史文章中學(xué)習(xí)Excel,Power Query,Power Pivot,Power BI,Power Automate各種技巧。
聯(lián)系客服