7.4.2 使用聚合操作進行計算
聚合背後的概念在於我們保持一些狀態,將在整個操作過程中傳遞。我們用乙個初始狀態開始,用給定的處理函式,為文件中的每個部件,計算乙個新的狀態。這種概念被反映在函式的簽名中:
val aggregatedocument :
('a -> documentpart -> 'a) -> 'a -> documentpart –> 'a
我們使用的廣義概念"一些狀態"的原因是,這種狀態可能是任何東西。在這個函式簽名中的狀態型別是乙個型別引數 'a,所以,它取決於這個函式的使用者。函式的後兩個引數值指定要處理的文件部件(這也表示整個文件)和狀態的初始值。aggregatedocument 的第乙個引數值是用於處理文件部件的函式,它基於舊的狀態和單個文件部件計算新狀態。清單 7.17 顯示了完整的實現(或許是令人驚訝的簡短)。
listing 7.17 aggregation of document parts (f#)
let rec aggregatedocument f state docpart =
let state = f state docpart
match docpart with
| titledpart(_, part) –>
aggregatedocument f state part
| splitpart(_, parts) ->
list.fold (aggregatedocument f) state parts
| _ –> state
**需要遍歷文件中的所有部件,它在當前部件上呼叫這個函式,然後,以遞迴方式處理所有子部件。與此相關的順序是:我們可以設計出函式,首先處理所有的子部件,然後是當前的部件。不同之處在清單 7.17 中,該函式會在樹的"根"節點上呼叫,而在其他情況下,可能會在"葉"節點上首先呼叫。對我們的目的而言,這兩個選項都工作正常,但對於一些高階的處理,我們可能必須考慮,想要哪一種遍歷方法。
當我們對當前部件呼叫這個聚合函式時,對要儲存新的狀態的值,使用相同的名字。新值隱藏舊值,在這裡,這是一項有用的安全措施: 它意味著,在我們已經計算出新的狀態以後,不會由於過失而意外使用原來的狀態。接下來,我們處理可能包含子部件的部件。對於標題部件,我們以遞迴方式處理正文。當我們獲得有子部件列表的拆分部件時,用列表上通常的聚合函式 list.fold 對它進行聚合。
聚合對於各種操作都是可用的。下面的**片斷展示了如何使用這個操作,來統計整個文件中的單詞數量:
let totalwords =
aggregatedocument (fun count part –>
match part with
| textpart(tx) | titledpart(tx, _) –>
count + tx.text.split(' ').length
| _ -> count) 0 doc
我們使用作為引數值的函式只關心包含文字的部件。我們有兩個這樣的部件,都包含 textcontent 型別值的文字。f# 的模式匹配,使我們能夠只使用有一種模式,處理兩種情況。這種語法稱為或模式(or-pattern),只能夠用在兩種模式繫結到值有相同型別的識別符號的情況。在我們的例子中,只需要乙個 textcontent 型別的識別符號(tx)。在模式匹配的正文中,我們把這個文字拆分成使用空格分隔的單詞,並加上返回陣列的長度作為計數。
注意 這裡有幾個建議,你可以在本書的**上找到, 或
■ 可以使用 mapdocument 來把超過500多個字元的文字部件拆分為兩列。
■ 可以使用聚合來收集一組用於文件的影象。
■ 可以實現類似篩選的操作,取乙個型別為 (documentpart -> bool)的函式,並建立文件,只包含該函式返回 true 的部件。使用這個函式,能夠從文件中刪除所有的影象。
我們已經看到,第二種表示便於對文件進行各種操作,特別是,如果我們首先實現了有用的高階函式。現在,我們要回到 c#,將討論我們剛才看到的適用於c# 程式設計的思想,以及它們如何與物件導向方法中眾所周知的概念相關。
7 4 2 使用聚合操作進行計算
7.4.2 使用聚合操作進行計算 聚合背後的概念在於我們保持一些狀態,將在整個操作過程中傳遞。我們用乙個初始狀態開始,用給定的處理函式,為文件中的每個部件,計算乙個新的狀態。這種概念被反映在函式的簽名中 val aggregatedocument a documentpart a a documen...
7 4 2 使用聚合操作進行計算
7.4.2 使用聚合操作進行計算 聚合背後的思想是,在整個操作過程中,傳遞的某些狀態能夠被保持。我們首先初始狀態,用給定的處理函式,為文件中的每個部分,計算出乙個新的狀態。這種思想反映在函式的簽名中 val aggregatedocument a documentpart a a documentp...
使用鏈路聚合進行負載分擔
資料流是指一組具有某個或某些相同屬性的資料報。這些屬性有源mac位址 目的mac位址 源ip位址 目的ip位址 tcp udp的源埠號 tcp udp的目的埠號等。在使用eth trunk 資料時,由於聚合組兩端裝置之間有多條物理鏈路,就會產生同一資料流的第乙個資料幀在一條物理鏈路上傳輸,而第二個資...