對映過濾並減少
標準庫中包含的兩個最基本的高階函式是 map
和 filter
。這些函式是通用的,可以在任何可迭代的函式上執行。特別是,它們非常適合在陣列上進行計算。
假設我們有一個學校資料集。每所學校都教授一門特定的科目,有多個類,每班平均學生人數。我們可以使用以下不可變型別為學校建模 :
immutable School
subject::Symbol
nclasses::Int
nstudents::Int # average no. of students per class
end
我們的學校資料集將是一個節目 3:
dataset = [School(:math, 3, 30), School(:math, 5, 20), School(:science, 10, 5)]
假設我們希望找到參加數學課程的學生總人數。為此,我們需要幾個步驟:
- 我們必須將資料集縮小到只教數學的學校(
filter
) - 我們必須計算每所學校的學生人數(
map
) - 我們必須將學生人數列表減少到單一值,總和(
reduce
)
一個天真的(不是最有效的)解決方案就是直接使用這三個高階函式。
function nmath(data)
maths = filter(x -> x.subject === :math, data)
students = map(x -> x.nclasses * x.nstudents, maths)
reduce(+, 0, students)
end
我們在資料集中驗證了 190 名數學學生:
julia> nmath(dataset)
190
存在用於組合這些功能並因此改善效能的功能。例如,我們可以使用 mapreduce
函式一步執行對映和縮減,這樣可以節省時間和記憶體。
reduce
僅對+
等關聯操作有意義,但偶爾使用非關聯操作執行縮減也很有用。提供高階函式 foldl
和 foldr
以強制執行特定的減少順序。