Zuordnen und Reduzieren in .NET

151

Welche Szenarien würden die Verwendung des Algorithmus " Map and Reduce " rechtfertigen ?


Gibt es eine .NET-Implementierung dieses Algorithmus?

Entwickler
quelle
4
Mögliches Duplikat der generischen
Listenerweiterungen

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/

Tony
quelle
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

Joel Martinez
quelle
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

CsUtil.com
quelle