F# 列表 SelectMany [英] F# List SelectMany

查看:18
本文介绍了F# 列表 SelectMany的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个很简单的问题,但我没有找到答案:

This is quite simple question but I didn't find an answer:

在 F# 中是否有任何 Seq/List 操作来匹配 LINQ SelectMany?

Is there any Seq/List operation in F# to match the LINQ SelectMany?

  • 我知道如果我可以在 F# 中使用 System.Linq想要.
  • 我知道我可以创建一个递归方法并使用 F# 计算表达式(并制作更强大的东西).

但是如果我试图证明 F# List 操作比 LINQ 更强大...

But if I try to prove that F# List operations are more powerful than LINQ...

  • .Where = List.filter
  • .Select = List.map
  • .Aggregate = List.fold
  • ...

在 C# 中 SelectMany 的使用语法非常简单:

In C# SelectMany usage syntax is pretty simple:

var flattenedList = from i in items1
                    from j in items2
                    select ...

是否有任何简单的直接匹配,List.flatten、List.bind 或类似的东西?

Is there any easy direct match, List.flatten, List.bind or something like that?

SelectMany 有几个签名,但最复杂的似乎是:

SelectMany has a couple of signatures, but the most complex one seems to be:

IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(
    this IEnumerable<TSource> source, 
    Func<TSource, IEnumerable<TCollection>> collectionSelector, 
    Func<TSource, TCollection, TResult> resultSelector
);

在 F# 术语中,这将是:

In F# terms this would be:

('a -> 'b list) -> ('a -> 'b -> 'c) -> 'a list -> 'c list

推荐答案

collect 是 SelectMany 的 F# 等效项,但它不提供所有重载.以下是制作您所引用的那个的方法.

collect is the F# equivalent of SelectMany however it doesn't provide all the overloads. Here's how to make the one you referenced.

let selectMany (ab:'a -> 'b seq) (abc:'a -> 'b -> 'c) input =
    input |> Seq.collect (fun a -> ab a |> Seq.map (fun b -> abc a b))
// gives
// val selectMany : ('a -> seq<'b>) -> ('a -> 'b -> 'c) -> seq<'a> -> seq<'c>

我相信 F# 没有提供所有 SelectMany 重载,因为它们会给库增加噪音.这是 Microsoft 中 SelectMany 的所有四个重载命名.

I believe F# doesn't provide all the SelectMany overloads because they would add noise to the library. Here's all four overloads to SelectMany in Microsoft Naming.

let selectMany (source : 'TSource seq) (selector : 'TSource -> 'TResult seq) =
    source |> Seq.collect selector

let selectMany (source : 'TSource seq) (selector : 'TSource -> int -> 'TResult seq) =
    source |> Seq.mapi (fun n s -> selector s n) |> Seq.concat

let selectMany (source : 'TSource) 
               (collectionSelector : 'TSource -> 'TCollection seq)
               (resultSelector : 'TSource -> 'TCollection -> 'TResult) =
    source 
    |> Seq.collect (fun sourceItem -> 
        collectionSelector sourceItem 
        |> Seq.map (fun collection -> resultSelector sourceItem collection))

let selectMany (source : 'TSource) 
               (collectionSelector : 'TSource -> int -> 'TCollection seq)
               (resultSelector : 'TSource -> 'TCollection -> 'TResult) =
    source 
    |> Seq.mapi (fun n sourceItem -> 
        collectionSelector sourceItem n
        |> Seq.map (fun collection -> resultSelector sourceItem collection))
    |> Seq.concat

F# 列表操作比 LINQ 更强大..."虽然 seq/列表操作很棒,但一些真正的F# 功能"来自 函数组合咖喱.

"F# List operations are more powerful than LINQ..." While seq / list operations are great some real "F# power" comes from Function Composition and Currying.

// function composition
let collect selector = Seq.map selector >> Seq.concat

这篇关于F# 列表 SelectMany的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆