异步处理子数组并将结果减少到单个数组

时间:2018-04-08 13:14:18

标签: arrays f#

输入如果输入采用数组数组的形式。

let items = [|
        [|"item1"; "item2"|]
        [|"item3"; "item4"|]
        [|"item5"; "item6"|]
        [|"item7"; "item8"|]
        [|"item9"; "item10"|]
        [|"item11"; "item12"|]
    |]

异步操作,返回异步结果或错误

let action (item: string) : Async<Result<string, string>> =
     async {
        return Ok (item + ":processed")
     }

尝试一次处理一个子阵列

let result = items
            |> Seq.map (Seq.map action >> Async.Parallel)
            |> Async.Parallel // wrong? process root items sequentially
            |> Async.RunSynchronously

期望

a)并行处理一个子阵列,然后并行处理第二个子阵列,依此类推。 (换句话说,根项的顺序处理和子项的并行处理)

b)然后收集所有结果并将它们合并为单个尺寸的结果数组,同时保持顺序。

c)最好使用ArraySeqListAsync等提供的内置方法,而不是任何自定义运算符(&#39}为不得已)

d)可选 - 如果它不可能在链中有某些东西,那么作为最后的手段可能会在最后将result子阵列转换为单个数组并返回给调用者,如果是导致我更喜欢清洁和简约的方法。

尝试2

let result2 = items
            |> Seq.map (Seq.map action >> Async.Parallel)
            |> Async.Parallel // wrong? is it processing root items sequentially
            |> Async.RunSynchronously
            |> Array.collect id


Array.iter (fun (item: Result<string, string>) ->
    match item with
    | Ok r -> Console.WriteLine(r)
    | Error e -> Console.WriteLine(e)
) result2

修改

let action (item: string) : Async<Result<string, string>> =
     async {
        return Ok (item + ":processed")
     }

let items = [| "item1"; "item2"; "item3"; "item4"; "item5"; "item6"; "item7"; "item8"; "item9"; "item10"|]

let result = items
          |> Seq.chunkBySize 2
          |> Seq.map (Seq.map action >> Async.Parallel)
          |> Seq.map Async.RunSynchronously
          |> Seq.toArray
          |> Array.collect id

1 个答案:

答案 0 :(得分:3)

let result = items |> Array.map ( Array.map action >> Async.Parallel)
                   |> Array.map Async.RunSynchronously
                   |> Array.collect id

编辑:请注意,Seq上定义的大多数操作都可以在数组中找到,反之亦然。如果你最初有一个数组,你可以一直使用数组操作。

let items = [| "item1"; "item2"; "item3"; "item4"; "item5"; "item6"; "item7"; "item8"; "item9"; "item10"|]

let result = items 
  |> Array.chunkBySize 2 
  |> Array.map (Array.map action >> Async.Parallel >> Async.RunSynchronously)          
  |> Array.concat