F#List.collect与C#List.SelectMany中的相同吗?

时间:2017-07-17 16:16:41

标签: c# linq f#

List.collect是否等同于LINQ List.SelectMany?

[1;2;3;4] |> List.collect (fun x -> [x * x]) // [1;4;9;16]
LINQ中的

new List<int>() { 1, 2, 3, 4 }
       .SelectMany(x => new List<int>() { x * x }); // 1;4;9;16

已编辑:

更合适的例子

let list1 = [1;2;3;4]
let list2 = [2;4;6]

// [2; 4; 6; 4; 8; 12; 6; 12; 18; 8; 16; 24]
list1 |> List.collect (fun a -> list2 |> List.map (fun b -> a * b)) 

...

var list1 = new List<int>() { 1, 2, 3, 4 };
var list2 = new List<int>() { 2, 4, 6 }

// 2,4,6,4,8,12,6,12,18,8,16,24
list1.SelectMany(a => list2.Select(b => a * b)); 

4 个答案:

答案 0 :(得分:11)

或多或少。相当于SelectMany的直接F#将是Seq.collect,其具有签名:

Seq.collect : ('T -> 'Collection) -> seq<'T> -> seq<'U> (requires 'Collection :> seq<'U>)

seq<'T>只是IEnumerable<T>的类型别名。

F#list是一个具体的集合(一个不可变的列表),因此List.collect被严格评估。

另请注意,F#list和.NET System.Collections.Generic.List<T>类型不相同。 System.Collections.Generic.List<T>是一个可变集合,通常通过F#中的类型别名ResizeArray<'T>引用。

答案 1 :(得分:8)

它们的行为相同但是Enumerable.SelectMany返回一个惰性序列(IEnumerable<T>),而List.collect返回严格创建的列表。另请注意,F#列表是持久链接列表,而C#列表由数组支持。

答案 2 :(得分:2)

只是想提一下,没有什么能阻止你直接在F#中使用LINQ扩展方法:

let list1 = [1;2;3;4]
let list2 = [2;4;6]
(list1,list2) ||> List.allPairs |> List.map (fun (a,b) -> a * b)
//val it : int list = [2; 4; 6; 4; 8; 12; 6; 12; 18; 8; 16; 24]

对于F#4.1中特定示例的更惯用的解决方案(尽管它仅适用于两个列表):

public class Test
{
    //All my classes have these properties
    //You can set up an interface and in the method you can set entity to an interface type
    //You can even put these interfaces on edmx generated entities
    //http://stackoverflow.com/questions/14059455/adding-validation-attributes-with-an-entity-framework-data-model
    public string AString { get; set; }
    public DateTime ADate { get; set; }
}

public class HomeController : Controller
{
    public ActionResult IndexStackOverflow101()
    {
        Assembly assembly = Assembly.Load("Testy20161006");
        Type t = assembly.GetType("Testy20161006.Controllers." + "Test");
        Object entity = (Object)Activator.CreateInstance(t);
        PropertyInfo entityProperty = t.GetProperty("AString");
        PropertyInfo entityPropertyTwo = t.GetProperty("ADate");
        entityProperty.SetValue(entity, Convert.ChangeType("ap", entityProperty.PropertyType), null);
        entityPropertyTwo.SetValue(entity, Convert.ChangeType(DateTime.Now, entityPropertyTwo.PropertyType), null);

答案 3 :(得分:0)

List.map是您正在寻找的功能。