将子数组异步处理并将结果缩减为单个数组。

3

输入 如果输入是由数组组成的数组。

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 等提供的内置方法,而不是任何自定义运算符(这应该是最后的选择)

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

Edit

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

这个问题有什么问题? - App2015
1个回答

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

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

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  

1
好的。谢谢。我有意隐藏了完整的图片,以缩小并强化这个顺序+并行思维,我在询问这个问题时遇到了困难,请查看完整的图片,并结合您的答案,可以吗? - App2015
太棒了。做得非常漂亮。是的,这是一个数组,使用Array版本。 - App2015

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接