巢狀陣列的資料處理(Processing Data in Cell Arrays)

儲存在巢狀陣列中的資料依據其實際的資料的類型可以有幾種不同的處理方式,最簡單的方式就是使用一個或多個迴圈來處理,或是直接使用 cellfun() 函數來處理,此函數會將使用者所指定的函數套用至巢狀陣列中的每一個元素。

cellfun (fname, c)
cellfun ("size", c, k)
cellfun ("isclass", c, k)
cellfun (func, c)
cellfun (func, c, d)
[a, b] = cellfun (...)
cellfun (..., "ErrorHandler", errfunc)
cellfun (..., "UniformOutput", val)

cellfun(fname, c) 函數會將指定的函數 fname 套用至巢狀陣列 c 中的每一個元素,c 中的每個元素會個別傳入 fname 函數中做處理,fname 可以指定為下列函數:

  • "isempty":測試是否為空元素。
  • "islogical":測試是否為邏輯值。
  • "isreal":測試是否為實數。
  • "length":傳回一個向量,向量中包含元素的長度。
  • "ndims":傳回元素的維度。
  • "prodofsize":傳回每個元素維度的乘積。
  • "size":傳回第 k 維的維度大小。
  • "isclass":測試元素的類別。

例如:

c = {"ABC", "12345"};
cellfun("length", c)

輸出為

ans =

   3   5

cellfun(func, c, d) 函數可以使用 inline function 或 function handle 的方式指定函數 func,而 cd 則是用於指定 func 輸入的參數,例如:

cellfun (@atan2, {1.1, 0.3}, {0.2, 1.4})

輸出為

ans =

   1.39094   0.21109

cellfun() 函數其預設的輸出是一個與輸入參數為度相同的陣列。

若參數 "UniformOutput" 設定為 true,則 func 所指定的函數必須傳回純量,這些純量會被連接起來而產生一個陣列,若設為 false,則 cellfun() 函數會傳回一個巢狀陣列,其中的元素是將輸入巢狀陣列 c 中的元素個別經過 func 函數處理後,再放進輸出巢狀陣列的對應位置,例如:

cellfun (@(x) tolower(x), {"Foo", "Bar", "FooBar"}, "UniformOutput", false)

輸出為

ans =

{
  [1,1] = foo
  [1,2] = bar
  [1,3] = foobar
}

"ErrorHandler" 參數可以將其後方的 errfunc 設定為錯誤處理函數,當 func 函數產生錯誤時,就會呼叫這個函數,此函數的格式為:

function [...] = errfunc (s, ...)

其中傳入的參數 s 是一個資料結構,其包含的欄位有:"identifier""message""index",分別代表錯誤的代碼與訊息,以及錯誤發生的資料位置,例如:

function y = foo (s, x), y = NaN; endfunction
cellfun (@factorial, {-1,2},'ErrorHandler',@foo)

輸出為

ans =

   NaN     2

另外一種巢狀陣列資料的處理方式是將巢狀陣列轉換為其他的資料容器,例如矩陣與資料結構。

m = cell2mat (c)

cell2mat(c) 函數會將巢狀陣列 c 轉換為矩陣,巢狀陣列 c 中的元素必須為數值、邏輯值或字串。

cell2struct (cell, fields, dim)

cell2struct(cell, fields, dim) 函數會將巢狀陣列 cell 轉換為資料結構,參數 fields 所指定的欄位數量必須等於 cell 維度 dim 的大小,即 numel (fields) == size (cell, dim)。例如:

cell = {'Peter', 'Hannah', 'Robert'; 185, 170, 168};
A = cell2struct (cell, {'Name','Height'}, 1);
A(1)

輸出為

ans =
{
  Name = Peter
  Height =  185
}