วิธีการต่อ LINQ“ พับ” อยู่ที่ไหน


95

ฉันพบในตัวอย่าง Linq ของ MSDN ซึ่งเป็นวิธีการที่เรียกว่า Fold () ที่ฉันต้องการใช้ ตัวอย่างของพวกเขา:

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

น่าเสียดายที่ฉันไม่สามารถรวบรวมสิ่งนี้ได้ทั้งในตัวอย่างหรือในโค้ดของฉันเองและฉันไม่พบที่อื่นใน MSDN (เช่นวิธีการ Enumerable หรือวิธีการขยาย Array) ที่พูดถึงวิธีนี้ ข้อผิดพลาดที่ฉันได้รับเป็นข้อผิดพลาด "ไม่รู้อะไรเลย" แบบเก่า:

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

ฉันใช้วิธีการอื่นที่ฉันเชื่อว่ามาจาก Linq (เช่น Select () และ Where ()) และฉันกำลัง "ใช้ System.Linq" ดังนั้นฉันคิดว่ามันก็โอเค

วิธีนี้มีอยู่จริงใน C # 3.5 หรือไม่ถ้าเป็นเช่นนั้นฉันทำอะไรผิด?


3
ตรวจสอบเส้นทางเศษขนมปัง * ในหน้าตัวอย่างที่คุณอ้างถึง - หมายถึง C # 3 เป็นผลิตภัณฑ์ในอนาคต สินค้าในอนาคตมักจะเปลี่ยนก่อนจัดส่ง เช่นเดียวกับคนอื่น ๆ ที่กล่าวถึงโปรดดูที่นับได้รวมและมีความสุข :) * Visual C # Developer Center> หน้าแรก> ข้อมูลผลิตภัณฑ์> เวอร์ชันในอนาคต> ตัวอย่าง LINQ 101 ตัว> ตัวดำเนินการรวม
Curt Nichols

คำตอบ:


127

คุณจะต้องใช้Aggregateวิธีการขยาย:

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

ดูMSDNสำหรับข้อมูลเพิ่มเติม ช่วยให้คุณระบุ a seedแล้วจึงเป็นนิพจน์เพื่อคำนวณค่าต่อเนื่อง


4
ควรสังเกตว่าคุณไม่จำเป็นต้องมีเมล็ดพันธุ์ด้วยเช่นกัน หากคุณเรียกโอเวอร์โหลดที่ไม่มีเมล็ดองค์ประกอบแรกในรายการจะถูกใช้เป็นค่าการรวมเริ่มต้นและFuncจะเรียกเมื่อถึงองค์ประกอบที่สองเท่านั้น ดู: msdn.microsoft.com/en-us/library/vstudio/…
Josh Gallagher

มันไม่พับถ้าฉันเข้าใจถูก: / การพับควรยอมรับทั้งสองอาร์กิวเมนต์ประเภทต่างๆ เช่นอาจเป็นอาร์กิวเมนต์แรกใช้สตริงและเมื่ออาร์กิวเมนต์ที่สองมีอะไรด้วยToString()จึงส่งคืนการแสดงข้อความของคอนเทนเนอร์ทั้งหมด
Hi-Angel

@ ไฮแองเจิ้ลไม่ตัวอย่างในความเป็นจริงพับ <double>พารามิเตอร์ชนิดเป็นเพียงการสรุปโดยอัตโนมัติโดยรวบรวมและดังนั้นจึงไม่จำเป็น
kdbanman

1
@ Hi-Angel pและelemจะเป็นแบบไหนก็ได้ ดูโอเวอร์โหลดตามที่ใช้ในตัวอย่างนี้
kdbanman

1
@kdbanman errr, ⁺¹มันน่าสนใจจริงๆว่าทำไมย้อนเวลากลับไปมันไม่ได้ผลสำหรับฉัน…: / ถูกต้องแล้วมันได้ผล
Hi-Angel

42

Fold (aka Reduce) เป็นคำมาตรฐานจากการเขียนโปรแกรมเชิงฟังก์ชัน ไม่ว่าด้วยเหตุผลใดจึงได้รับการตั้งชื่อว่าAggregateใน LINQ

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

9
Aggregate เป็นคำที่คุ้นเคยมากกว่าในขอบเขต OO และ SQL
Adam Robinson

3
ไม่ทราบถึงคีย์เวิร์ด CREATE AGGREGATE ( msdn.microsoft.com/en-us/library/ms182741.aspx ) เรียนรู้สิ่งใหม่ ๆ ทุกวัน
Richard Berg

5
ตลกดีฉันไม่เคยได้ยินคำว่า "รวม" นอก SQL WP มีรายการen.wikipedia.org/wiki/Fold_(higher-order_function)สองสามภาษาและ C # เป็นภาษาเดียวที่เรียกมันว่า "Aggregate" "ลด" คือผู้ชนะที่ชัดเจนตามด้วย "พับ" สำหรับครอบครัว ML และ "ฉีด" สำหรับ Smalltalk และเพื่อน ๆ
เคน

12
ชื่อเป็นเรื่องของฟังก์ชันการทำงาน วิธีการใช้งานไม่เกี่ยวข้อง และ FWIW การพับซ้ายจะถูกนำมาใช้ซ้ำ ๆ เมื่อเป็นไปได้ ... ในภาษาที่ใช้งานได้มักจะผ่านการเรียกซ้ำหาง และ C # ไม่มีการพับขวาซึ่งส่วนหนึ่งเป็นผลมาจากการเลือกชื่อโง่ ๆ - แม้ว่าจะไม่เลวร้ายเท่ากับ "เลือก" สำหรับ "แผนที่" - และเพิกเฉยต่อเทคโนโลยีการทำงานที่มีอยู่ สำหรับ Aggregate เป็นคำที่คุ้นเคยกันมากขึ้นในขอบเขต OO ... ไม่ไม่เลย
Jim Balter

9
เพื่อความเป็นธรรมฉันไม่คิดว่า Microsoft จะไม่สนใจเทคโนโลยีการทำงานหรือคำศัพท์ที่มีอยู่ แต่เป็นการวางแนวทางในการเข้าถึงฐานข้อมูลและคำศัพท์ของ SQL ซึ่งโปรแกรมเมอร์ระดับองค์กรหลายคนอาจคุ้นเคยมากกว่าคำว่าการเขียนโปรแกรมเชิงฟังก์ชัน
RavuAlHemio
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.