แผนที่และลดใน. NET


152

สถานการณ์ใดบ้างที่รับประกันการใช้อัลกอริทึม" แผนที่และลดลง "


มีการใช้. NET ของอัลกอริทึมนี้หรือไม่?


4
อาจเป็นไปได้ซ้ำกับส่วนขยายรายการทั่วไปใน C #
Satpal

คำตอบ:


298

Linq เทียบเท่ากับ Map and Reduce: หากคุณโชคดีพอที่จะมี linq คุณไม่จำเป็นต้องเขียนแผนที่ของคุณเองและลดฟังก์ชั่น C # 3.5 และ Linq มีอยู่แล้วภายใต้ชื่ออื่น

  • แผนที่คือSelect:

    Enumerable.Range(1, 10).Select(x => x + 2);
  • ลดคือAggregate:

    Enumerable.Range(1, 10).Aggregate(0, (acc, x) => acc + x);
  • ตัวกรองคือWhere:

    Enumerable.Range(1, 10).Where(x => x % 2 == 0);

https://www.justinshield.com/2011/06/mapreduce-in-c/


1
การแปลถูกต้อง แต่พลาดจุดสำคัญ ขั้นตอนการสับเปลี่ยนในการลดแผนที่มีความสำคัญอย่างยิ่งในการลดแผนที่ แต่ไม่ปรากฏในชื่อและไม่จำเป็นต้องเขียนโค้ดใด ๆ เลย มันถูกขับเคลื่อนโดยกุญแจที่สกัดในขั้นตอนแผนที่ โจเอลมาร์ติเนซตอบว่าไฮไลต์ในความคิดของฉันดีกว่า
xtofs

2
ลิงก์ไม่ทำงานลิงก์ที่ถูกต้องคือ: justinshield.com/2011/06/mapreduce-in-c
Alexandru-Dan Pop

12
ทำไมโอ้ทำไมพวกเขาถึงไม่เรียกมันว่าReduceแทนAggregate... MS แค่ชอบรบกวนโปรแกรมเมอร์
John Henckel

13
@ JohnHenckel ฉันไม่ใช่แหล่งข้อมูลที่เชื่อถือได้ แต่ฉันค่อนข้างแน่ใจว่าสิ่งนี้มาจาก SQL ฉันเชื่อว่า linq นั้นซื้อมาในรูปแบบเดิมเพื่อให้สามารถโต้ตอบกับ sql ได้ง่ายขึ้นใน C # เมื่อคุณตั้งชื่อฟังก์ชั่นในโลกนั้นการรวมเริ่มจะฟังดูคุ้นเคยมากกว่า "ลด" เมื่อเปรียบเทียบกับสิ่งที่เลือกและจัดกลุ่มตาม ฉันไม่ได้บอกว่าถูกต้องมันทำให้ฉันรำคาญไม่สิ้นสุด แต่ฉันคิดว่านั่นเป็นเหตุผลสำหรับมัน
เอลเลียตแบล็กเบิร์น

18

คลาสของปัญหาที่เหมาะสมกับโซลูชันสไตล์ mapreduce เป็นปัญหาของการรวม จากการดึงข้อมูลจากชุดข้อมูล ใน C # เราสามารถใช้ประโยชน์จาก LINQ ในการเขียนโปรแกรมในรูปแบบนี้

จากบทความต่อไปนี้: http://codecube.net/2009/02/mapreduce-in-c-using-linq/

วิธีการ GroupBy ทำหน้าที่เป็นแผนที่ในขณะที่วิธีการเลือกทำงานของการลดผลกลางที่เป็นรายการสุดท้ายของผลลัพธ์

var wordOccurrences = words
                .GroupBy(w => w)
                .Select(intermediate => new
                {
                    Word = intermediate.Key,
                    Frequency = intermediate.Sum(w => 1)
                })
                .Where(w => w.Frequency > 10)
                .OrderBy(w => w.Frequency);

สำหรับส่วนที่กระจายคุณสามารถตรวจสอบ DryadLINQ: http://research.microsoft.com/en-us/projects/dryadlinq/default.aspx


3

ตั้งแต่ผมจำไม่ได้ว่า LINQ เรียกมันWhere, SelectและAggregateแทนFilter, MapและReduceดังนั้นฉันสร้างวิธีการขยายบางอย่างที่คุณสามารถใช้:

IEnumerable<string> myStrings = new List<string>() { "1", "2", "3", "4", "5" };
IEnumerable<int> convertedToInts = myStrings.Map(s => int.Parse(s));
IEnumerable<int> filteredInts = convertedToInts.Filter(i => i <= 3); // Keep 1,2,3
int sumOfAllInts = filteredInts.Reduce((sum, i) => sum + i); // Sum up all ints
Assert.Equal(6, sumOfAllInts); // 1+2+3 is 6

นี่คือ 3 วิธี (จากhttps://github.com/cs-util-com/cscore/blob/master/CsCore/PlainNetClassLib/src/Plugins/CsCore/com/csutil/collections/IEnumerableExtensions.cs ):

public static IEnumerable<R> Map<T, R>(this IEnumerable<T> self, Func<T, R> selector) {
    return self.Select(selector);
}

public static T Reduce<T>(this IEnumerable<T> self, Func<T, T, T> func) {
    return self.Aggregate(func);
}

public static IEnumerable<T> Filter<T>(this IEnumerable<T> self, Func<T, bool> predicate) {
    return self.Where(predicate);
}

รายละเอียดเพิ่มเติมบางส่วนจากhttps://github.com/cs-util-com/cscore#ienumerable-extensions :

ป้อนคำอธิบายรูปภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.