Das mag lahm klingen, aber ich konnte keine wirklich gute Erklärung dafür finden Aggregate
.
Gut bedeutet kurz, beschreibend, umfassend mit einem kleinen und klaren Beispiel.
Die am einfachsten zu verstehende Definition von Aggregate
ist, dass für jedes Element der Liste eine Operation ausgeführt wird, wobei die zuvor durchgeführten Operationen berücksichtigt werden. Das heißt, es führt die Aktion für das erste und zweite Element aus und überträgt das Ergebnis. Dann arbeitet es mit dem vorherigen Ergebnis und dem dritten Element und überträgt es. usw.
Beispiel 1. Zahlen summieren
var nums = new[]{1,2,3,4};
var sum = nums.Aggregate( (a,b) => a + b);
Console.WriteLine(sum); // output: 10 (1+2+3+4)
Dies fügt hinzu 1
und 2
zu machen 3
. Dann werden 3
(Ergebnis des vorherigen) und 3
(nächstes Element in Folge) hinzugefügt, um zu machen 6
. Dann fügt hinzu 6
und 4
zu machen 10
.
Beispiel 2. Erstellen Sie eine CSV aus einem Array von Zeichenfolgen
var chars = new []{"a","b","c", "d"};
var csv = chars.Aggregate( (a,b) => a + ',' + b);
Console.WriteLine(csv); // Output a,b,c,d
Dies funktioniert ähnlich. Verketten Sie a
ein Komma und b
machen Sie a,b
. Dann a,b
mit einem Komma verketten und c
machen a,b,c
. und so weiter.
Beispiel 3. Multiplizieren von Zahlen mit einem Startwert
Der Vollständigkeit halber ist es eine Überlast von Aggregate
dem einen Ausgangswert annimmt.
var multipliers = new []{10,20,30,40};
var multiplied = multipliers.Aggregate(5, (a,b) => a * b);
Console.WriteLine(multiplied); //Output 1200000 ((((5*10)*20)*30)*40)
Ähnlich wie in den obigen Beispielen beginnt dies mit einem Wert von 5
und multipliziert ihn mit dem ersten Element der Sequenz 10
, das ein Ergebnis von ergibt 50
. Dieses Ergebnis wird übertragen und mit der nächsten Zahl in der Sequenz multipliziert 20
, um ein Ergebnis von zu erhalten 1000
. Dies setzt sich durch die verbleibenden 2 Elemente der Sequenz fort.
Live-Beispiele: http://rextester.com/ZXZ64749
Dokumente: http://msdn.microsoft.com/en-us/library/bb548651.aspx
Nachtrag
In Beispiel 2 oben wird die Verkettung von Zeichenfolgen verwendet, um eine durch Komma getrennte Liste von Werten zu erstellen. Dies ist eine vereinfachte Methode, um die Verwendung Aggregate
dieser Antwort zu erklären . Wenn Sie diese Technik jedoch verwenden, um tatsächlich eine große Menge von durch Kommas getrennten Daten zu erstellen, ist es besser, a zu verwenden StringBuilder
, und dies ist vollständig kompatibel mit der Aggregate
Verwendung der gesetzten Überladung, um die zu initiieren StringBuilder
.
var chars = new []{"a","b","c", "d"};
var csv = chars.Aggregate(new StringBuilder(), (a,b) => {
if(a.Length>0)
a.Append(",");
a.Append(b);
return a;
});
Console.WriteLine(csv);
Aktualisiertes Beispiel: http://rextester.com/YZCVXV6464
[1,2,3,4]
wird es[3,3,4]
dann[6,4]
und endlich sein[10]
. Anstatt ein Array mit einem einzelnen Wert zurückzugeben, erhalten Sie nur den Wert selbst.TakeWhile
dannAggregate
- das ist die Pflicht von Enumerable-Erweiterungen - sie sind leicht verkettbar. So enden Sie mitTakeWhile(a => a == 'a').Aggregate(....)
. Siehe dieses Beispiel: rextester.com/WPRA60543var csv = string.Join(",", chars)
(kein Aggregat oder Stringbuilder erforderlich) - aber ja, ich weiß, der Sinn der Antwort bestand darin, eine beispielhafte Verwendung des Aggregats anzugeben, damit es cool ist. Aber ich wollte immer noch erwähnen, dass es nicht empfohlen wird, nur Strings zu verbinden, dafür gibt es bereits eine Methode ...var biggestAccount = Accounts.Aggregate((a1, a2) => a1.Amount >= a2.Amount ? a1 : a2);
Es hängt teilweise davon ab, von welcher Überlastung Sie sprechen, aber die Grundidee ist:
(currentValue, sequenceValue)
in die transformiert werden soll(nextValue)
currentValue = nextValue
currentValue
Sie können den
Aggregate
Beitrag in meiner Edulinq-Reihe nützlich finden - er enthält eine detailliertere Beschreibung (einschließlich der verschiedenen Überladungen) und Implementierungen.Ein einfaches Beispiel ist die Verwendung
Aggregate
als Alternative zuCount
:Oder vielleicht alle Längen von Strings in einer Folge von Strings summieren:
Persönlich finde ich das selten
Aggregate
nützlich - die "maßgeschneiderten" Aggregationsmethoden sind normalerweise gut genug für mich.quelle
Superkurzes Aggregat funktioniert wie Fold in Haskell / ML / F #.
Etwas länger .Max (), .Min (), .Sum (), .Average () durchlaufen alle Elemente in einer Sequenz und aggregieren sie mit der jeweiligen Aggregatfunktion. .Aggregate () ist ein verallgemeinerter Aggregator, der es dem Entwickler ermöglicht, den Startstatus (auch bekannt als Seed) und die Aggregatfunktion anzugeben.
Ich weiß, dass Sie um eine kurze Erklärung gebeten haben, aber ich dachte, als andere ein paar kurze Antworten gaben, dachte ich, dass Sie vielleicht an einer etwas längeren interessiert sein würden
Lange Version mit Code Eine Möglichkeit, um zu veranschaulichen, was dies bedeutet, besteht darin, zu zeigen, wie Sie die Beispielstandardabweichung einmal mit foreach und einmal mit .Aggregate implementieren. Hinweis: Ich habe die Leistung hier nicht priorisiert, daher iteriere ich unnötig mehrmals über die Sammlung
Zuerst eine Hilfsfunktion, mit der eine Summe quadratischer Abstände erstellt wird:
Dann probieren Sie die Standardabweichung mit ForEach:
Dann einmal mit .Aggregate:
Beachten Sie, dass diese Funktionen identisch sind, außer wie sumOfQuadraticDistance berechnet wird:
Gegen:
Was .Aggregate also tut, ist, dass es dieses Aggregatormuster kapselt, und ich gehe davon aus, dass die Implementierung von .Aggregate ungefähr so aussehen würde:
Die Verwendung der Standardabweichungsfunktionen würde ungefähr so aussehen:
meiner bescheidenen Meinung nach
Hilft .Aggregate also bei der Lesbarkeit? Im Allgemeinen liebe ich LINQ, weil ich denke, dass .Where, .Select, .OrderBy usw. die Lesbarkeit erheblich verbessern (wenn Sie inlinierte hierarhische .Selects vermeiden). Aggregate muss aus Gründen der Vollständigkeit in Linq sein, aber ich persönlich bin nicht so überzeugt, dass .Aggregate die Lesbarkeit im Vergleich zu einem gut geschriebenen Foreach erhöht.
quelle
SampleStandardDeviation_Aggregate()
undSampleStandardDeviation_ForEach()
können nicht seinprivate
(standardmäßig in Abwesenheit eines Zugriffsqualifizierers), sollten also entwederpublic
oderinternal
, wie mir scheintEin Bild sagt mehr als tausend Worte
Enumerable.Aggregate hat drei Überladungen:
Überladung 1:
Beispiel:
Diese Überlastung ist einfach, weist jedoch die folgenden Einschränkungen auf:
sonst löst die Funktion ein
InvalidOperationException
.Überladung 2:
Beispiel:
Diese Überlastung ist allgemeiner:
bIn
).In diesem Fall liefert die Funktion als Ergebnis den Startwert.
Überladung 3:
Die dritte Überlastung ist IMO nicht sehr nützlich.
Dasselbe kann prägnanter geschrieben werden, indem Überladung 2 gefolgt von einer Funktion verwendet wird, die das Ergebnis transformiert.
quelle
Aggegate
in .net, die eine benötigtFunc<T, T, T>
.seed
, die Akkumulatorfunktion N -1 mal anwendet ; während die anderen Überlastungen (das sich ein Takeseed
) gelten die Akkumulatorfunktion N mal.Aggregat wird grundsätzlich zum Gruppieren oder Zusammenfassen von Daten verwendet.
Laut MSDN "Aggregatfunktion Wendet eine Akkumulatorfunktion über eine Sequenz an."
Beispiel 1: Fügen Sie alle Zahlen in einem Array hinzu.
* wichtig: Der anfängliche Aggregatwert ist standardmäßig das 1-Element in der Erfassungssequenz. dh: Der Anfangswert der Gesamtvariablen ist standardmäßig 1.
variable Erklärung
total: Es enthält den von der Funktion zurückgegebenen Summenwert (aggregierter Wert).
nextValue: Dies ist der nächste Wert in der Array-Sequenz. Dieser Wert wird dann zum aggregierten Wert addiert, dh insgesamt.
Beispiel 2: Fügen Sie alle Elemente in einem Array hinzu. Stellen Sie außerdem den anfänglichen Akkumulatorwert so ein, dass ab 10 mit dem Hinzufügen begonnen wird.
Argumente Erklärung:
Das erste Argument ist der Anfangsbuchstabe (Startwert, dh Startwert), mit dem die Addition mit dem nächsten Wert im Array gestartet wird.
Das zweite Argument ist eine Funktion, die 2 int benötigt.
1.total: Dies gilt genauso wie vor dem Summenwert (aggregierter Wert), der von der Funktion nach der Berechnung zurückgegeben wird.
2.nextValue :: Dies ist der nächste Wert in der Array-Sequenz. Dieser Wert wird dann zum aggregierten Wert addiert, dh insgesamt.
Wenn Sie diesen Code auch debuggen, erhalten Sie ein besseres Verständnis für die Funktionsweise von Aggregaten.
quelle
Ich habe viel aus Jamiecs Antwort gelernt .
Wenn Sie nur eine CSV-Zeichenfolge generieren müssen, können Sie dies versuchen.
Hier ist ein Test mit 1 Million Zeichenfolgen
Der Quellcode ist hier
quelle
Zusätzlich zu all den tollen Antworten hier habe ich es auch verwendet, um einen Gegenstand durch eine Reihe von Transformationsschritten zu führen.
Wenn eine Transformation als a implementiert ist
Func<T,T>
, können Sie a mehrere Transformationen hinzufügenList<Func<T,T>>
undAggregate
eine Instanz vonT
durch jeden Schritt führen.Ein konkreteres Beispiel
Sie möchten einen
string
Wert nehmen und ihn durch eine Reihe von Texttransformationen führen, die programmgesteuert erstellt werden können.Dadurch wird eine Kette von Transformationen erstellt: Entfernen Sie führende und nachfolgende Leerzeichen -> entfernen Sie das erste Zeichen -> entfernen Sie das letzte Zeichen -> konvertieren Sie in Großbuchstaben. Schritte in dieser Kette können nach Bedarf hinzugefügt, entfernt oder neu angeordnet werden, um die erforderliche Transformationspipeline zu erstellen.
Das Endergebnis dieser speziellen Pipeline, ist , dass
" cat "
wird"A"
.Dies kann sehr mächtig werden, sobald Sie erkennen, dass
T
dies alles sein kann . Dies könnte für Bildtransformationen wie Filter amBitMap
Beispiel verwendet werden.quelle
Die Aggregatmethode ist eine Erweiterungsmethode für generische Sammlungen. Die Aggregatmethode wendet eine Funktion auf jedes Element einer Sammlung an. Wendet nicht nur eine Funktion an, sondern nimmt ihr Ergebnis als Anfangswert für die nächste Iteration. Als Ergebnis erhalten wir einen berechneten Wert (min, max, avg oder einen anderen statistischen Wert) aus einer Sammlung.
Daher ist die Aggregatmethode eine Form der sicheren Implementierung einer rekursiven Funktion.
Sicher , da die Rekursion über jedes Element einer Sammlung iteriert und wir durch eine falsche Ausgangsbedingung keine Endlosschleifenaufhängung erhalten können. Rekursiv , da das Ergebnis der aktuellen Funktion als Parameter für den nächsten Funktionsaufruf verwendet wird.
Wie es funktioniert:
das macht das gleiche wie diese Funktion:
quelle
Dies ist eine Erklärung zur Verwendung
Aggregate
in einer Fluent-API wie Linq Sorting.und lassen Sie uns sehen, dass wir eine Sortierfunktion implementieren möchten, die eine Reihe von Feldern verwendet. Dies ist sehr einfach
Aggregate
anstelle einer for-Schleife wie folgt :Und wir können es so verwenden:
quelle
Jeder hat seine Erklärung gegeben. Meine Erklärung ist so.
Die Aggregatmethode wendet eine Funktion auf jedes Element einer Sammlung an. Nehmen wir zum Beispiel die Sammlung {6, 2, 8, 3} und die Funktion Add (Operator +), die sie ausführt (((6 + 2) +8) +3) und gibt 19 zurück
In diesem Beispiel wird anstelle des Lambda-Ausdrucks die benannte Methode Add übergeben.
quelle
Eine kurze und wesentliche Definition könnte folgende sein: Die Linq Aggregate-Erweiterungsmethode ermöglicht es, eine Art rekursive Funktion zu deklarieren, die auf die Elemente einer Liste angewendet wird, deren Operanden zwei sind: die Elemente in der Reihenfolge, in der sie in der Liste vorhanden sind, jeweils ein Element und das Ergebnis der vorherigen rekursiven Iteration oder nichts, wenn noch keine Rekursion.
Auf diese Weise können Sie die Fakultät für Zahlen berechnen oder Zeichenfolgen verketten.
quelle
Aggregat zum Summieren von Spalten in einem mehrdimensionalen Ganzzahlarray
Mit Index auswählen wird in der Aggregatfunktion verwendet, um die übereinstimmenden Spalten zu summieren und ein neues Array zurückzugeben. {3 + 2 = 5, 1 + 4 = 5, 7 + 16 = 23, 8 + 5 = 13}.
Das Zählen der Anzahl von Wahrheiten in einem Booleschen Array ist jedoch schwieriger, da sich der akkumulierte Typ (int) vom Quelltyp (bool) unterscheidet. hier ist ein Samen notwendig, um die zweite Überladung zu nutzen.
quelle