在單元格和陣列上執行的有用函式
這個簡單的例子提供了一些解釋,我發現自從我開始使用 MATLAB 以來非常有用的一些函式:cellfun
,arrayfun
。我們的想法是獲取一個陣列或單元類變數,遍歷其所有元素並在每個元素上應用專用函式。應用函式可以是匿名的,通常是一種情況,也可以是* .m 檔案中定義的任何常規函式。
讓我們從一個簡單的問題開始,並說我們需要找到給定該資料夾的* .mat 檔案列表。對於此示例,首先讓我們在當前資料夾中建立一些* .mat 檔案:
for n=1:10; save(sprintf('mymatfile%d.mat',n)); end
執行程式碼後,應該有 10 個副檔名為* .mat 的新檔案。如果我們執行命令列出所有* .mat 檔案,例如:
mydir = dir('*.mat');
我們應該得到一個 dir 結構元素的陣列; MATLAB 應該給出一個類似的輸出:
10x1 struct array with fields:
name
date
bytes
isdir
datenum
如你所見,此陣列的每個元素都是一個包含幾個欄位的結構。所有資訊對於每個檔案確實很重要,但在 99%中我對檔名很感興趣而沒有別的。為了從結構陣列中提取資訊,我曾經建立了一個本地函式,它涉及建立正確大小的時間變數,for 迴圈,從每個元素中提取名稱,並將其儲存到建立的變數中。實現完全相同結果的更簡單方法是使用上述功能之一:
mydirlist = arrayfun(@(x) x.name, dir('*.mat'), 'UniformOutput', false)
mydirlist =
'mymatfile1.mat'
'mymatfile10.mat'
'mymatfile2.mat'
'mymatfile3.mat'
'mymatfile4.mat'
'mymatfile5.mat'
'mymatfile6.mat'
'mymatfile7.mat'
'mymatfile8.mat'
'mymatfile9.mat'
這個功能如何運作?它通常需要兩個引數:一個函式控制代碼作為第一個引數和一個陣列。然後,函式將對給定陣列的每個元素進行操作。第三和第四個引數是可選的但很重要。如果我們知道輸出不是常規輸出,則必須將其儲存在單元格中。必須指出將 false
設定為 UniformOutput
。預設情況下,此函式會嘗試返回常規輸出,例如數字向量。例如,讓我們提取有關每個檔案佔用多少磁碟空間的資訊(以位元組為單位):
mydirbytes = arrayfun(@(x) x.bytes, dir('*.mat'))
mydirbytes =
34560
34560
34560
34560
34560
34560
34560
34560
34560
34560
或千位元組:
mydirbytes = arrayfun(@(x) x.bytes/1024, dir('*.mat'))
mydirbytes =
33.7500
33.7500
33.7500
33.7500
33.7500
33.7500
33.7500
33.7500
33.7500
33.7500
這次輸出是 double 的常規向量。UniformOutput
預設設定為 true
。
cellfun
是一個類似的功能。這個函式和 arrayfun
之間的區別在於 cellfun
對單元類變數進行操作。如果我們希望僅在單元格’mydirlist’中提取檔名列表中的名稱,我們只需要按如下方式執行此函式:
mydirnames = cellfun(@(x) x(1:end-4), mydirlist, 'UniformOutput', false)
mydirnames =
'mymatfile1'
'mymatfile10'
'mymatfile2'
'mymatfile3'
'mymatfile4'
'mymatfile5'
'mymatfile6'
'mymatfile7'
'mymatfile8'
'mymatfile9'
同樣,由於輸出不是常規數字向量,因此輸出必須儲存在單元格變數中。
在下面的示例中,我將兩個函式合併為一個,並僅返回沒有副檔名的檔名列表:
cellfun(@(x) x(1:end-4), arrayfun(@(x) x.name, dir('*.mat'), 'UniformOutput', false), 'UniformOutput', false)
ans =
'mymatfile1'
'mymatfile10'
'mymatfile2'
'mymatfile3'
'mymatfile4'
'mymatfile5'
'mymatfile6'
'mymatfile7'
'mymatfile8'
'mymatfile9'
它很瘋狂但很可能因為 arrayfun
返回了一個預期輸入 cellfun
的單元格; 對此的一個注意事項是,我們可以通過將 UniformOutput
設定為 false 來強制顯式地將任何這些函式返回到單元格變數中。我們總能在單元格中獲得結果。我們可能無法在常規向量中獲得結果。
還有一個類似的函式在欄位上執行一個結構:structfun
。我沒有特別發現它和其他兩個一樣有用但在某些情況下它會發光。例如,如果想知道哪些欄位是數字或非數字,則以下程式碼可以給出答案:
structfun(@(x) ischar(x), mydir(1))
dir 結構的第一個和第二個欄位是 char 型別。因此,輸出是:
1
1
0
0
0
此外,輸出是 true
/ false
的邏輯向量。因此,它是常規的,可以儲存在向量中; 不需要使用單元格類。