Phương pháp mở rộng LINQ “Gấp” ở đâu?


95

Tôi tìm thấy trong các mẫu Linq của MSDN một phương thức gọn gàng được gọi là Fold () mà tôi muốn sử dụng. Ví dụ của họ:

double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 }; 
double product = 
     doubles.Fold((runningProduct, nextFactor) => runningProduct * nextFactor); 

Thật không may, tôi không thể lấy điều này để biên dịch, trong ví dụ của họ hoặc trong mã của riêng tôi và tôi không thể tìm thấy bất kỳ nơi nào khác trong MSDN (như các phương thức mở rộng Enumerable hoặc Array) đề cập đến phương pháp này. Lỗi tôi nhận được là một lỗi cũ rõ ràng "không biết gì về điều đó":

error CS1061: 'System.Array' does not contain a definition for 'Fold' and no 
extension method 'Fold' accepting a first argument of type 'System.Array' could 
be found (are you missing a using directive or an assembly reference?)

Tôi đang sử dụng các phương pháp khác mà tôi tin rằng đến từ Linq (như Select () và Where ()) và tôi đang "sử dụng System.Linq", vì vậy tôi nghĩ rằng tất cả đều ổn.

Phương pháp này có thực sự tồn tại trong C # 3.5 không, và nếu vậy, tôi đang làm gì sai?


3
Kiểm tra dấu vết vụn bánh mì * trên trang mẫu mà bạn đã tham khảo - nó đề cập đến C # 3 như một sản phẩm trong tương lai. Các sản phẩm trong tương lai thường thay đổi trước khi xuất xưởng. Giống như những người khác đã đề cập, hãy xem Enumerable.Aggregate và vui chơi. :) * Visual C # Developer Center> Trang chủ> Thông tin Sản phẩm> Các phiên bản trong tương lai> 101 LINQ Samples> tổng hợp khai thác
Curt Nichols

Câu trả lời:


126

Bạn sẽ muốn sử dụng Aggregatephương thức mở rộng:

double product = doubles.Aggregate(1.0, (prod, next) => prod * next);

Xem MSDN để biết thêm thông tin. Nó cho phép bạn chỉ định a seedvà sau đó là một biểu thức để tính các giá trị liên tiếp.


4
Cần lưu ý rằng bạn cũng không cần phải có hạt giống. Nếu bạn gọi quá tải không có hạt giống thì phần tử đầu tiên trong danh sách được sử dụng làm giá trị tổng hợp ban đầu và phần tử Funcchỉ được gọi khi đạt đến phần tử thứ hai. Xem: msdn.microsoft.com/en-us/library/vstudio/…
Josh Gallagher

Nó không được gấp nếu tôi hiểu đúng: / Màn hình đầu tiên phải chấp nhận cả hai đối số thuộc các loại khác nhau. Ví dụ, một đối số có thể như đối số đầu tiên sử dụng một chuỗi, và đối số thứ hai có thể sử dụng bất kỳ thứ gì ToString(), do đó trả về biểu diễn văn bản của toàn bộ vùng chứa.
Hi-Angel

@ Hi-Angel, không, ví dụ trên thực tế là một nếp gấp. Các <double>tham số kiểu được chỉ tự động suy ra bởi trình biên dịch và do đó không cần thiết.
kdbanman

1
@ Hi-Angel, pelemcó thể là bất kỳ kiểu nào bạn thích. Xem quá tải này như được sử dụng trong ví dụ này
kdbanman

1
@kdbanman errr, ⁺¹, thật thú vị tại sao trước đây nó không hoạt động với tôi…: / Bạn nói đúng, nó hoạt động.
Hi-Angel

42

Fold (hay còn gọi là Reduce) là thuật ngữ tiêu chuẩn của lập trình chức năng. Vì lý do gì, nó được đặt tên là Aggregate trong LINQ.

double product = doubles.Aggregate(1.0, (runningProduct, nextFactor) => runningProduct* nextFactor);

9
Aggregate là một thuật ngữ quen thuộc hơn trong lĩnh vực OO và SQL.
Adam Robinson

3
Không biết từ khóa CREATE AGGREGATE ( msdn.microsoft.com/en-us/library/ms182741.aspx ) Học điều gì đó mới mỗi ngày.
Richard Berg

5
Thật buồn cười, tôi chưa bao giờ nghe thấy "tổng hợp" bên ngoài SQL. WP có một danh sách en.wikipedia.org/wiki/Fold_(higher-order_ Chức năng) gồm hàng chục ngôn ngữ và C # là ngôn ngữ duy nhất gọi nó là "Aggregate". "Giảm" là người chiến thắng rõ ràng, tiếp theo là "Gấp" cho gia đình ML và "Tiêm" cho Smalltalk và bạn bè.
Ken

12
Tên là một vấn đề về chức năng của nó; nó được thực hiện như thế nào là không liên quan. Và FWIW, các nếp gấp bên trái được thực hiện lặp đi lặp lại khi có thể ... trong các ngôn ngữ chức năng thường thông qua đệ quy đuôi. Và C # không có nếp gấp phù hợp, một phần là hệ quả của việc chọn một cái tên ngu ngốc - mặc dù không tệ như "select" cho "bản đồ" - và bỏ qua công nghệ chức năng hiện có. Đối với Aggregate là một thuật ngữ quen thuộc hơn trong lĩnh vực OO ... không, không hề.
Jim Balter

9
Công bằng mà nói, tôi không cho rằng đó là việc Microsoft coi thường công nghệ hoặc thuật ngữ chức năng hiện có, mà là định hướng của nó đối với quyền truy cập cơ sở dữ liệu và thuật ngữ SQL, mà nhiều lập trình viên doanh nghiệp có lẽ quen thuộc hơn các thuật ngữ lập trình chức năng.
RavuAlHemio
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.