问题描述
这是一个非常简单的问题,但我没有找到答案:
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#计算表达式(并使功能更强大).
- I know I can use System.Linq in F# if Iwant to.
- I know I can make a recursive methodand use F# Computation Expressions(and make even more powerful things).
但是,如果我试图证明F#List操作比LINQ更强大...
But if I try to prove that F# List operations are more powerful than LINQ...
- .Where = List.filter
- .选择= 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#表示,这将是:
('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/list操作非常有用,但某些真正的"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#列表选择很多的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!