2015-04-20 40 views
1

我有一個映射減少代碼,我通過某個鍵在每個線程中分組,然後在reduce部分中合併結果。我目前的做法是尋找在累加器的特定密鑰索引,然後MAPI只爲這個鍵檢索綜合作用的結果,留下其餘不變:基於鍵的功能摺疊

let rec groupFolder sequence acc = 
    match sequence with 
     | (by:string, what) :: rest -> 
      let index = acc |> Seq.tryFindIndex(fun (byInAcc, _) -> byInAcc.Equals(by)) 
      match index with 
       | Some (idx) -> 
           acc |> Seq.mapi(fun i (byInAcc, whatInAcc) -> if i = idx then (by, (what |> Array.append whatInAcc)) else byInAcc, whatInAcc) 
            |> groupFolder rest 

       | None -> acc |> Seq.append(seq{ yield (by, what) }) 
           |> groupFolder rest 

我的問題是,是它功能更強的方式實現這一目標?

由於輸入到該減速器

let GroupsCommingFromMap = [| seq { yield! [|("key1", [|1;2;3|]); ("key2", [|1;2;3|]); ("key3", [|1;2;3|]) |] }, seq { yield! [|("key1", [|4;5;6|]); ("key2", [|4;5;6|]); ("key3", [|4;5;6|]) |] } |];; 

GroupsCommingFromMap |> Seq.reduce(fun acc i -> 
            acc |> groupFolder (i |> Seq.toList)) 

一個例子,預期的結果應包含所有key1..key3每個陣列1..6

回答

2

從您發佈的代碼,是不是很清楚你想要做什麼。你能否包括一些樣本輸入(連同你想得到的輸出)?你的代碼實際上是否在任何輸入上工作(它有不完全的模式匹配,所以我懷疑...)

無論如何,你可以使用Seq.groupBy實現基於鍵的映射減少。例如:

let mapReduce mapper reducer input = 
    input 
    |> Seq.map mapper 
    |> Seq.groupBy fst 
    |> Seq.map (fun (k, vs) -> 
     k, vs |> Seq.map snd |> Seq.reduce reducer) 

這裏:

  • mapper從輸入序列取值並把它變成關鍵值對。該mapReduce功能,然後組用關鍵
  • reducer然後被用來減少與每個鍵

這樣可以創建這樣一個字計數功能相關聯的所有值的值(使用簡單映射器返回字與1的值和減速的關鍵,只是將所有的數字):

"hello world hello people hello world".Split(' ') 
|> mapReduce (fun w -> w, 1) (+) 

編輯:你提到確實沒有「映射」的部分,而是它有數組的數組作爲例子一個輸入 - 所以perhap s更容易直接使用Seq.groupBy這樣寫:

let GroupsCommingFromMap = 
    [| [|("key1", [|1;2;3|]); ("key2", [|1;2;3|]); ("key3", [|1;2;3|]) |] 
    [|("key1", [|4;5;6|]); ("key2", [|4;5;6|]); ("key3", [|4;5;6|]) |] |] 

GroupsCommingFromMap 
|> Seq.concat 
|> Seq.groupBy fst 
|> Seq.map (fun (k, vs) -> k, vs |> Seq.map snd |> Array.concat) 
+0

謝謝Tomas爲您解答。我添加了一個來自mapper的示例結果以及我期待的內容。所以按羣組是答案。當然,那麼我可以簡單地追加第二次減少。我已經在舌尖了。 – user3853059

+0

@ user3853059添加了一個樣本來處理您描述的情況。 –

+0

哦,我忘了提到映射器自己做了一個group,它只是以我在示例中給出的格式返回組。再次感謝您的回答 – user3853059