2017-07-17 20 views
6

Có phải List.collect tương đương với Danh sách LINQ.SelectMany không?Là F # List.collect giống như trong C# List.SelectMany?

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

trong LINQ

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

được sửa đổi:

dụ Thích hợp hơn

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)); 
+3

với mô tả tại https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/list.collect%5B't%2C'u%5D-function-%5Bfsharp% 5D, nó chắc chắn trông giống như vậy với tôi. –

+1

(Mặc dù ví dụ của bạn không hoạt động, trong đó bạn dường như đã chuyển từ tăng gấp đôi thành bình phương một nửa ...) –

+0

@Jon Skeet Tôi đã thay đổi nó – kogoia

Trả lời

11

Nhiều hơn hoặc ít hơn. Trực tiếp F # tương đương với SelectMany sẽ Seq.collect trong đó có chữ ký:

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

seq<'T> chỉ là một loại bí danh cho IEnumerable<T>.

F # list là bộ sưu tập cụ thể (danh sách không thể thay đổi) và do đó được đánh giá đúng mức là List.collect.

Cũng lưu ý rằng các loại F # list và .NET System.Collections.Generic.List<T> không tương đương. System.Collections.Generic.List<T> là một bộ sưu tập có thể thay đổi và thường được gọi qua bí danh loại ResizeArray<'T> trong F #.

0

List.map là hàm bạn đang tìm kiếm.

+10

Không tương đương với 'SelectMany' -' List.map' tương đương với 'Select', phải không? –

8

Chúng hoạt động giống nhau tuy nhiên Enumerable.SelectMany trả về một chuỗi lười (IEnumerable<T>) trong khi List.collect trả về danh sách được tạo đúng. Cũng lưu ý rằng danh sách F # là danh sách liên kết liên tục trong khi danh sách C# được hỗ trợ bởi một mảng.

+0

Cảm ơn bạn, điều này rất hữu ích đối với tôi – kogoia

2

Chỉ muốn đề cập rằng không có gì sẽ ngăn cản bạn từ việc sử dụng các phương pháp khuyến nông LINQ trực tiếp trong F #:

open System.Linq 
open System.Collections.Generic 
open System 

let xs = seq [seq [1;2;3]; seq [4;5;6]] 
xs.SelectMany(fun x -> x).Select(fun x -> x * x) 
// val it: IEnumerable<int> = seq [1; 4; 9; 16; ...] 

Và đối với một giải pháp nhiều thành ngữ ví dụ cụ thể của bạn trong F # 4.1 (mặc dù nó chỉ hoạt động trên hai danh sách):

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] 
Các vấn đề liên quan