Das mag lahm klingen, aber ich habe noch keine wirklich gute Erklärung gefunden für Aggregate
.
Gut bedeutet kurz, beschreibend, umfassend und mit einem kleinen, klaren Beispiel.
Das mag lahm klingen, aber ich habe noch keine wirklich gute Erklärung gefunden für Aggregate
.
Gut bedeutet kurz, beschreibend, umfassend und mit einem kleinen, klaren Beispiel.
Zusätzlich zu all den großartigen Antworten, die hier bereits gegeben wurden, habe ich es auch verwendet, um einen Artikel durch eine Reihe von Transformationsschritten zu führen.
Wenn eine Transformation als Func<T,T>
können Sie mehrere Transformationen zu einer List<Func<T,T>>
und verwenden Aggregate
um eine Instanz von T
durch jeden Schritt.
Sie möchten eine string
Wert, und führen Sie ihn durch eine Reihe von Texttransformationen, die programmatisch erstellt werden können.
var transformationPipeLine = new List<Func<string, string>>();
transformationPipeLine.Add((input) => input.Trim());
transformationPipeLine.Add((input) => input.Substring(1));
transformationPipeLine.Add((input) => input.Substring(0, input.Length - 1));
transformationPipeLine.Add((input) => input.ToUpper());
var text = " cat ";
var output = transformationPipeLine.Aggregate(text, (input, transform)=> transform(input));
Console.WriteLine(output);
Dadurch wird eine Kette von Transformationen erzeugt: Führende und nachfolgende Leerzeichen entfernen -> erstes Zeichen entfernen -> letztes Zeichen entfernen -> in Großbuchstaben umwandeln. Die Schritte in dieser Kette können je nach Bedarf hinzugefügt, entfernt oder umgeordnet werden, um eine beliebige Art von Transformationspipeline zu erstellen.
Das Endergebnis dieser speziellen Pipeline ist, dass " cat "
wird "A"
.
Dies kann sehr wirkungsvoll sein, wenn Sie erkennen, dass T
kann sein alles . Dies könnte für Bildtransformationen, wie z. B. Filter, verwendet werden, indem BitMap
als Beispiel;
Definition
Die Aggregatmethode ist eine Erweiterungsmethode für generische Sammlungen. Die Aggregate-Methode wendet eine Funktion auf jedes Element einer Sammlung an. Sie wendet nicht nur eine Funktion an, sondern nimmt deren Ergebnis als Anfangswert für die nächste Iteration. Als Ergebnis erhalten wir also einen berechneten Wert (Min, Max, Avg oder einen anderen statistischen Wert) aus einer Sammlung.
Deshalb, Die Aggregatmethode ist eine Form der sicheren Implementierung einer rekursiven Funktion.
Sicher weil die Rekursion über jedes Element einer Sammlung iteriert und wir keine Endlosschleifenunterbrechung durch eine falsche Ausgangsbedingung erhalten können. Rekursiv denn das Ergebnis der aktuellen Funktion wird als Parameter für den nächsten Funktionsaufruf verwendet.
Syntax:
collection.Aggregate(seed, func, resultSelector);
Wie es funktioniert:
var nums = new[]{1, 2};
var result = nums.Aggregate(1, (result, n) => result + n); //result = (1 + 1) + 2 = 4
var result2 = nums.Aggregate(0, (result, n) => result + n, response => (decimal)response/2.0); //result2 = ((0 + 1) + 2)*1.0/2.0 = 3*1.0/2.0 = 3.0/2.0 = 1.5
Praktische Anwendung:
Ermitteln des Faktors aus einer Zahl n:
int n = 7; var numbers = Enumerable.Range(1, n); var factorial = numbers.Aggregate((result, x) => result * x);
die das Gleiche tut wie diese Funktion:
public static int Factorial(int n)
{
if (n < 1) return 1;
return n * Factorial(n - 1);
}
Aggregate() ist eine der mächtigsten LINQ-Erweiterungsmethoden, wie Select() und Where(). Wir können sie verwenden, um die Funktionen Sum(), Min(). Max(), Avg() zu ersetzen oder sie durch die Implementierung von Zusatzkontext zu ändern:
var numbers = new[]{3, 2, 6, 4, 9, 5, 7};
var avg = numbers.Aggregate(0.0, (result, x) => result + x, response => (double)response/(double)numbers.Count());
var min = numbers.Aggregate((result, x) => (result < x)? result: x);
Komplexere Verwendung von Erweiterungsmethoden:
var path = @“c:\path-to-folder”;
string[] txtFiles = Directory.GetFiles(path).Where(f => f.EndsWith(“.txt”)).ToArray<string>();
var output = txtFiles.Select(f => File.ReadAllText(f, Encoding.Default)).Aggregate<string>((result, content) => result + content);
File.WriteAllText(path + “summary.txt”, output, Encoding.Default);
Console.WriteLine(“Text files merged into: {0}”, output); //or other log info
Dies ist eine Erklärung zur Verwendung von Aggregate
auf eine Fluent-API wie Linq Sorting.
var list = new List<Student>();
var sorted = list
.OrderBy(s => s.LastName)
.ThenBy(s => s.FirstName)
.ThenBy(s => s.Age)
.ThenBy(s => s.Grading)
.ThenBy(s => s.TotalCourses);
und lassen Sie uns sehen, dass wir eine Sortierfunktion implementieren wollen, die einen Satz von Feldern annimmt, dies ist sehr einfach mit Aggregate
anstelle einer for-Schleife, etwa so:
public static IOrderedEnumerable<Student> MySort(
this List<Student> list,
params Func<Student, object>[] fields)
{
var firstField = fields.First();
var otherFields = fields.Skip(1);
var init = list.OrderBy(firstField);
return otherFields.Skip(1).Aggregate(init, (resultList, current) => resultList.ThenBy(current));
}
Und wir können es so verwenden:
var sorted = list.MySort(
s => s.LastName,
s => s.FirstName,
s => s.Age,
s => s.Grading,
s => s.TotalCourses);
Aggregat zur Addition von Spalten in einem mehrdimensionalen Integer-Array
int[][] nonMagicSquare =
{
new int[] { 3, 1, 7, 8 },
new int[] { 2, 4, 16, 5 },
new int[] { 11, 6, 12, 15 },
new int[] { 9, 13, 10, 14 }
};
IEnumerable<int> rowSums = nonMagicSquare
.Select(row => row.Sum());
IEnumerable<int> colSums = nonMagicSquare
.Aggregate(
(priorSums, currentRow) =>
priorSums.Select((priorSum, index) => priorSum + currentRow[index]).ToArray()
);
Select mit Index wird innerhalb der Aggregate-Funktion 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 }.
Console.WriteLine("rowSums: " + string.Join(", ", rowSums)); // rowSums: 19, 27, 44, 46
Console.WriteLine("colSums: " + string.Join(", ", colSums)); // colSums: 25, 24, 45, 42
Das Zählen der Anzahl der Wahrheiten in einem booleschen Array ist jedoch schwieriger, da sich der akkumulierte Typ (int) vom Quelltyp (bool) unterscheidet; hier ist ein Seed erforderlich, um die zweite Überladung zu verwenden.
bool[][] booleanTable =
{
new bool[] { true, true, true, false },
new bool[] { false, false, false, true },
new bool[] { true, false, false, true },
new bool[] { true, true, false, false }
};
IEnumerable<int> rowCounts = booleanTable
.Select(row => row.Select(value => value ? 1 : 0).Sum());
IEnumerable<int> seed = new int[booleanTable.First().Length];
IEnumerable<int> colCounts = booleanTable
.Aggregate(seed,
(priorSums, currentRow) =>
priorSums.Select((priorSum, index) => priorSum + (currentRow[index] ? 1 : 0)).ToArray()
);
Console.WriteLine("rowCounts: " + string.Join(", ", rowCounts)); // rowCounts: 3, 1, 2, 2
Console.WriteLine("colCounts: " + string.Join(", ", colCounts)); // colCounts: 3, 2, 1, 2
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.