Di manakah Metode Ekstensi LINQ "Lipat"?

95

Saya menemukan dalam sampel Linq MSDN sebuah metode rapi yang disebut Fold () yang ingin saya gunakan. Contoh mereka:

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

Sayangnya, saya tidak bisa mendapatkan ini untuk dikompilasi, baik dalam contoh mereka atau dalam kode saya sendiri, dan saya tidak dapat menemukan tempat lain di MSDN (seperti metode ekstensi Enumerable atau Array) yang menyebutkan metode ini. Kesalahan yang saya dapatkan adalah kesalahan lama "tidak tahu apa-apa tentang itu":

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?)

Saya menggunakan metode lain yang saya percaya berasal dari Linq (seperti Select () dan Where ()), dan saya "menggunakan System.Linq", jadi saya pikir itu semua OK.

Apakah metode ini benar-benar ada di C # 3.5, dan jika demikian, apa yang saya lakukan salah?

Ken
sumber
3
Lihat jejak remah roti * pada halaman contoh yang Anda referensikan - mengacu pada C # 3 sebagai produk masa depan. Produk masa depan sering berubah sebelum dikirimkan. Seperti yang lain disebutkan, lihat Enumerable. Agregate and have fun. :) * Visual C # Developer Center> Beranda> Informasi Produk> Versi Mendatang> 101 Sampel LINQ> Operator Agregat
Curt Nichols

Jawaban:

126

Anda akan ingin menggunakan Aggregatemetode ekstensi:

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

Lihat MSDN untuk informasi lebih lanjut. Ini memungkinkan Anda menentukan seeddan kemudian ekspresi untuk menghitung nilai yang berurutan.

Jason
sumber
4
Perlu dicatat bahwa Anda juga tidak harus memiliki benih. Jika Anda memanggil overload yang tidak memiliki seed maka elemen pertama dalam daftar akan digunakan sebagai nilai agregat awal dan Funchanya dipanggil setelah elemen kedua tercapai. Lihat: msdn.microsoft.com/en-us/library/vstudio/…
Josh Gallagher
Itu bukan lipatan jika saya mengerti benar: / Lipatan harus menerima kedua argumen dari jenis yang berbeda. Misalnya, salah satu argumen pertama dapat menggunakan string, dan sebagai argumen kedua dengan apa pun ToString(), dengan demikian mengembalikan representasi teks dari seluruh wadah.
Hi-Angel
@ Hi-Angel, tidak, contohnya adalah lipatan. The <double>jenis parameter hanya secara otomatis disimpulkan oleh compiler dan dengan demikian tidak perlu.
kdbanman
1
@ Hi-Angel, pdan elembisa tipe apapun yang Anda suka. Lihat kelebihan beban ini seperti yang digunakan dalam contoh ini
kdbanman
1
@kdbanman errr, ⁺¹, sangat menarik mengapa dulu itu tidak berhasil untuk saya…: / Anda benar, itu berhasil.
Hi-Angel
42

Lipat (alias Reduce) adalah istilah standar dari pemrograman fungsional. Untuk alasan apa pun, itu dinamai Agregat di LINQ.

double product = doubles.Aggregate(1.0, (runningProduct, nextFactor) => runningProduct* nextFactor);
Richard Berg
sumber
9
Agregat adalah istilah yang lebih dikenal di ranah OO dan SQL.
Adam Robinson
3
Tidak mengetahui kata kunci CREATE AGGREGATE ( msdn.microsoft.com/en-us/library/ms182741.aspx ) Pelajari sesuatu yang baru setiap hari.
Richard Berg
5
Lucu, saya belum pernah mendengar "agregat" di luar SQL. WP memiliki daftar en.wikipedia.org/wiki/Fold_(higher-order_function) dari beberapa lusin bahasa dan C # adalah satu-satunya yang menyebutnya "Agregat". "Reduce" adalah pemenang yang jelas, diikuti oleh "Fold" untuk keluarga ML, dan "Inject" untuk Smalltalk dan teman-teman.
Ken
12
Nama adalah masalah fungsinya; bagaimana itu diterapkan tidak relevan. Dan FWIW, lipatan kiri diimplementasikan secara berulang jika memungkinkan ... dalam bahasa fungsional biasanya melalui rekursi ekor. Dan C # tidak memiliki lipatan kanan, yang sebagian merupakan konsekuensi dari memilih nama yang bodoh - meskipun tidak seburuk "pilih" untuk "peta" - dan mengabaikan teknologi fungsional yang ada. Adapun Agregat menjadi istilah yang lebih akrab di ranah OO ... tidak, tidak sama sekali.
Jim Balter
9
Agar adil, saya tidak menganggap Microsoft mengabaikan teknologi atau terminologi fungsional yang ada, tetapi orientasinya terhadap akses database dan terminologi SQL, yang mungkin lebih dikenal oleh banyak programmer perusahaan daripada istilah pemrograman fungsional.
RavuAlHemio