7 4 2 使用聚合操作進行計算

2021-06-27 07:06:21 字數 1938 閱讀 5381

7.4.2 使用聚合操作進行計算

聚合背後的思想是,在整個操作過程中,傳遞的某些狀態能夠被保持。我們首先初始狀態,用給定的處理函式,為文件中的每個部分,計算出乙個新的狀態。這種思想反映在函式的簽名中:

val aggregatedocument :

('a -> documentpart -> 'a)-> 'a -> documentpart –> 'a

我們之所以使用「某些狀態」這樣的寬泛概念,原因是狀態可能是任意的。在函式簽名中,狀態的型別是型別引數 'a,因此,它取決於函式的使用者。函式的後兩個引數指定要處理的文件部分(也表示整個文件)和狀態的初始值。aggregatedocument 的第乙個引數是處理文件部分的函式,它根據原來的狀態和乙個文件部分計算出新的狀態。清單 7.17 顯示了完整(且或許是驚人的簡短)的實現。

清單 7.17 聚合文件各部分 (f#)

let rec aggregatedocument f state docpart =

let state = f state docpart    [1]

match docpart with

| titledpart(_, part) –>

aggregatedocument f statepart    [2]

| splitpart(_, parts) ->

list.fold(aggregatedocument f) state parts    [3]

| _ –> state

**需要遍歷文件中的所有部分,它在當前部件上呼叫函式,然後,遞迴地處理所有子部分。在這裡,順序是重要的:我們已經設計的函式,可能首先處理所有子部分,然後再處理當前的部分。差別在於,清單 7.17 中,在樹的「根」節點上呼叫函式,而在其他情況下,可能會首先在「葉子」節點上呼叫。對我們的目的而言,這兩種順序都正確,但對於一些高階的處理,我們可能必須考慮哪一種遍歷方法。

當我們對當前部分呼叫聚合函式時[1],使用同名值保持新的狀態,新值隱藏了舊值,在這裡,這是一項有效的安全措施:因為我們不可能在已經計算出新的狀態以後,由於過失而意外使用原來的狀態。接下來,我們處理可能包含子部分的部分。對於有標題部分,我們以遞迴方式處理正文[2]。當我們得到有子部分列表的分欄部分時,用列表上通常的聚合函式 list.fold [3]對它進行聚合。

聚合對於多種型別都可能是有用的。下面的**片斷展示了如何使用這個操作,統計整個文件中的單詞數量:

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 documen...

使用鏈路聚合進行負載分擔

資料流是指一組具有某個或某些相同屬性的資料報。這些屬性有源mac位址 目的mac位址 源ip位址 目的ip位址 tcp udp的源埠號 tcp udp的目的埠號等。在使用eth trunk 資料時,由於聚合組兩端裝置之間有多條物理鏈路,就會產生同一資料流的第乙個資料幀在一條物理鏈路上傳輸,而第二個資...