Zuordnen und Reduzieren in .NET


Antworten:


297

Linq-Äquivalente von Map und Reduce: Wenn Sie das Glück haben, Linq zu haben, müssen Sie keine eigene Map schreiben und Funktionen reduzieren. C # 3.5 und Linq haben es bereits, wenn auch unter verschiedenen Namen.

  • Karte ist Select:

    Enumerable.Range(1, 10).Select(x => x + 2);
  • Reduzieren ist Aggregate:

    Enumerable.Range(1, 10).Aggregate(0, (acc, x) => acc + x);
  • Filter ist Where:

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

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


1
Die Übersetzung ist korrekt, aber es fehlt ein wichtiger Punkt. Der Shuffle-Schritt bei der Kartenreduzierung ist bei der Kartenreduzierung von entscheidender Bedeutung, wird jedoch nicht im Namen angezeigt, und es muss kein Code dafür geschrieben werden. Es wird ausschließlich von dem Schlüssel gesteuert, der im Kartenschritt extrahiert wird. Joel Martinez Antwort hebt das meiner Meinung nach besser hervor.
xtofs

2
Link funktioniert nicht, korrekter Link ist: justinshield.com/2011/06/mapreduce-in-c
Alexandru-Dan Pop

12
Warum oh, warum nennen sie es nicht einfach Reducestatt Aggregate... MS nervt nur gerne Programmierer
John Henckel

13
@ JohnHenckel, ich bin definitiv keine maßgebliche Quelle, aber ich bin mir ziemlich sicher, dass dies aus SQL stammt. Ich glaube, linq wurde ursprünglich gekauft, um die Interaktion mit SQL in C # zu vereinfachen. Wenn Sie Funktionen in dieser Welt benennen, klingt das Aggregat im Vergleich zu "Auswählen" und "Gruppieren nach" etwas vertrauter als "Reduzieren". Ich sage nicht, dass es richtig ist, es nervt mich ohne Ende, aber ich stelle mir vor, das ist der Grund dafür.
Elliot Blackburn

18

Die Problemklassen, die für eine Mapreduce-Lösung gut geeignet sind, sind Aggregationsprobleme. Daten aus einem Datensatz extrahieren. In C # könnte man LINQ nutzen, um in diesem Stil zu programmieren.

Aus dem folgenden Artikel: http://codecube.net/2009/02/mapreduce-in-c-using-linq/

Die GroupBy-Methode fungiert als Zuordnung, während die Select-Methode die Zwischenergebnisse in die endgültige Ergebnisliste reduziert.

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

Den verteilten Teil finden Sie unter DryadLINQ: http://research.microsoft.com/en-us/projects/dryadlinq/default.aspx


2

Da kann ich nie , dass LINQ nennt sie erinnern Where, Selectund Aggregatestatt Filter, Mapund Reduceso habe ich ein paar Erweiterungsmethoden erstellt wurden, können Sie verwenden:

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

Hier sind die 3 Methoden (von 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);
}

Weitere Informationen finden Sie unter https://github.com/cs-util-com/cscore#ienumerable-extensions :

Geben Sie hier die Bildbeschreibung ein

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.