學習軌道
/
Tcl
Tcl
/
練習
/
陣列操作
陣列操作

陣列操作

中等

說明

實作基本的陣列操作。

在函式式語言中,length、map和reduce這類陣列操作非常常見。請在不使用現有函式的情況下,實作一系列基本的陣列操作。

要實作的操作,其確切數量和名稱會依 track 而有所不同,以避免與現有名稱衝突,但你會實作的一般操作包括:

  • append(給定兩個陣列,把第二個陣列中的所有項目加到第一個陣列的尾端);
  • concatenate(給定一連串的陣列,把所有陣列中的所有項目合併成一個攤平的陣列);
  • filter(給定一個述詞和一個陣列,回傳所有 predicate(item) 為 True 的項目所組成的陣列);
  • length(給定一個陣列,回傳其中項目的總數);
  • map(給定一個函式和一個陣列,回傳對所有項目套用 function(item) 所得結果的陣列);
  • foldl(給定一個函式、一個陣列和初始累加器,從左側將每個項目摺疊(縮減)進累加器);
  • foldr(給定一個函式、一個陣列和一個初始累加器,從右側將每個項目摺疊(縮減)進累加器);
  • reverse(給定一個陣列,回傳一個包含所有原始項目、但順序相反的陣列)。

請注意,傳遞給摺疊函式(foldl、foldr)的引數順序很重要。

Tcl 的 apply 指令

測試案例看起來可能令人困惑。 你需要實作的是:

set myList {alpha beta gamma delta}
listOps::filter $myList {{word} {expr {[string length $word] == 4}}

為什麼最後那個引數有這麼多的大括號?

回想一下,proc 指令的定義是:

proc procName argList body

Tcl 有一個 apply 指令:

apply func ?arg1 arg2 ...?

這個「func」是一個兩元素的串列 {argList body},本質上就是一個匿名 proc(或「lambda」)。 apply 指令會呼叫那個匿名 proc,並把它需要的引數傳進去。

舉例來說,以下這些寫法是等價的:

# using proc
proc myReverse {str} {return [string reverse $str]}
puts [myReverse "Hello, World!"]

# using apply
puts [apply {{str} {string reverse $str}} "Hello, World!"]

# or, store the func in a variable
set func {{str} {string reverse $str}}
puts [apply $func "Hello, World!"]

使用 apply 可以更輕鬆地傳遞程式碼區塊。

參考:apply、proc。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Tcl Exercism

準備好開始 陣列操作 了嗎?

註冊 Exercism,透過 135 個練習 和真人引導來學習並精通 Tcl,全部免費。

深入探索 陣列操作!

享受一場實用的遞迴入門,探索陣列操作的指令式與函式風格替代做法,並深入鑽研尾端遞迴與累加器函式。