Może zabrzmi to kiepsko, ale nie udało mi się znaleźć naprawdę dobrego wytłumaczenia Aggregate
.
Dobry oznacza krótki, opisowy, kompleksowy z małym i wyraźnym przykładem.
Najłatwiejszą do zrozumienia definicją Aggregate
jest to, że wykonuje operację na każdym elemencie listy, biorąc pod uwagę operacje, które zostały wykonane wcześniej. Oznacza to, że wykonuje akcję na pierwszym i drugim elemencie i przenosi wynik do przodu. Następnie działa na poprzednim wyniku i trzecim elemencie i kontynuuje. itp.
Przykład 1. Sumowanie liczb
var nums = new[]{1,2,3,4};
var sum = nums.Aggregate( (a,b) => a + b);
Console.WriteLine(sum); // output: 10 (1+2+3+4)
To dodaje 1
i 2
robi 3
. Następnie dodaje 3
(wynik z poprzedniego) i 3
(następny element w sekwencji) do wykonania 6
. Następnie dodaje 6
i 4
do zrobienia 10
.
Przykład 2. utwórz plik csv z tablicy ciągów
var chars = new []{"a","b","c", "d"};
var csv = chars.Aggregate( (a,b) => a + ',' + b);
Console.WriteLine(csv); // Output a,b,c,d
Działa to w podobny sposób. Połącz a
przecinek i b
wykonaj a,b
. Następnie konkatenuje a,b
przecinek i c
tworzy a,b,c
. i tak dalej.
Przykład 3. Mnożenie liczb za pomocą zarodka
Dla kompletności, jest przeciążenie od Aggregate
którego przyjmuje wartość nasion.
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)
Podobnie jak w powyższych przykładach, zaczyna się od wartości 5
i mnoży ją przez pierwszy element sekwencji, 10
dając wynik 50
. Ten wynik jest przenoszony do przodu i mnożony przez następną liczbę w sekwencji, 20
aby dać wynik 1000
. Kontynuuje to przez pozostałe 2 elementy sekwencji.
Przykłady na żywo: http://rextester.com/ZXZ64749
Dokumenty: http://msdn.microsoft.com/en-us/library/bb548651.aspx
Uzupełnienie
W powyższym przykładzie 2 zastosowano konkatenację łańcuchów, aby utworzyć listę wartości oddzielonych przecinkiem. Jest to uproszczony sposób objaśnienia, którego użycie Aggregate
było celem tej odpowiedzi. Jeśli jednak użyjesz tej techniki do faktycznego utworzenia dużej liczby danych oddzielonych przecinkami, bardziej odpowiednie byłoby użycie a StringBuilder
, i jest to całkowicie zgodne z Aggregate
użyciem inicjowanego przeciążenia do zainicjowania 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);
Zaktualizowany przykład: http://rextester.com/YZCVXV6464
[1,2,3,4]
będzie[3,3,4]
potem[6,4]
, a wreszcie[10]
. Ale zamiast zwracać tablicę pojedynczej wartości, dostajesz samą wartość.TakeWhile
następnieAggregate
- który jest hitem rozszerzeń Enumerable - można je łatwo łączyć. Więc skończysz zTakeWhile(a => a == 'a').Aggregate(....)
. Zobacz ten przykład: rextester.com/WPRA60543var csv = string.Join(",", chars)
(bez potrzeby agregacji lub konstruktorów ciągów) - ale tak, wiem, że celem odpowiedzi było podanie przykładowego użycia agregacji, aby było fajne. Ale nadal chciałem wspomnieć, że nie jest to zalecane do łączenia ciągów, istnieje już metoda przeznaczona do tego ....var biggestAccount = Accounts.Aggregate((a1, a2) => a1.Amount >= a2.Amount ? a1 : a2);
Zależy to częściowo od tego, o którym przeciążeniu mówisz, ale podstawową ideą jest:
(currentValue, sequenceValue)
w(nextValue)
currentValue = nextValue
currentValue
Może się
Aggregate
przydać post z mojej serii Edulinq - zawiera bardziej szczegółowy opis (w tym różne przeciążenia) i implementacje.Jednym prostym przykładem jest użycie
Aggregate
jako alternatywy dlaCount
:A może sumując wszystkie długości ciągów w sekwencji ciągów:
Osobiście rzadko uważam za
Aggregate
użyteczne - „dostosowane” metody agregacji są zazwyczaj dla mnie wystarczające.źródło
Super krótki agregat działa jak fold w Haskell / ML / F #.
Nieco dłuższe .Max (), .Min (), .Sum (), .Average () wszystkie iterują elementy w sekwencji i agregują je za pomocą odpowiedniej funkcji agregującej. .Aggregate () jest uogólnionym agregatorem, ponieważ umożliwia programistom określenie stanu początkowego (inaczej seed) i funkcji agregującej.
Wiem, że poprosiłeś o krótkie wyjaśnienie, ale pomyślałem, że gdy inni udzielili kilku krótkich odpowiedzi, pomyślałem, że być może zainteresuje Cię nieco dłuższa
Długa wersja z kodem Jednym ze sposobów zilustrowania, co to może być, pokazanie, w jaki sposób zaimplementowano przykładowe odchylenie standardowe przy użyciu foreach i raz .gregat. Uwaga: nie nadałem tutaj priorytetu wydajności, więc kilkakrotnie iteruję niepotrzebnie
Najpierw funkcja pomocnicza używana do utworzenia sumy kwadratowych odległości:
Następnie przykładowe odchylenie standardowe za pomocą ForEach:
Następnie po użyciu .Aggregate:
Zauważ, że te funkcje są identyczne, z wyjątkiem sposobu obliczania sumOfQuadraticDistance:
Przeciw:
Więc .Aggregate robi to, że hermetyzuje ten wzorzec agregatora i oczekuję, że implementacja .Aggregate będzie wyglądać mniej więcej tak:
Korzystanie z funkcji odchylenia standardowego wyglądałoby mniej więcej tak:
moim zdaniem
Czy więc .Aggregate poprawia czytelność? Ogólnie uwielbiam LINQ, ponieważ myślę .Gdzie, .Select, .OrderBy i tak dalej znacznie poprawia czytelność (jeśli unikniesz wbudowanych hierarhicznych. Agregat musi być w Linq ze względów kompletności, ale osobiście nie jestem przekonany, że Agregat zwiększa czytelność w porównaniu do dobrze napisanego foreach.
źródło
SampleStandardDeviation_Aggregate()
iSampleStandardDeviation_ForEach()
nie może byćprivate
(domyślnie w przypadku braku dostępu eliminacjach), więc powinny zostać naliczone przez jednąpublic
lubinternal
, wydaje mi sięObraz jest wart tysiąca słów
Enumerable.Aggregate ma trzy przeciążenia:
Przeciążenie 1:
Przykład:
To przeciążenie jest proste, ale ma następujące ograniczenia:
przeciwnym razie funkcja wyrzuci an
InvalidOperationException
.Przeciążenie 2:
Przykład:
To przeciążenie jest bardziej ogólne:
bIn
).w takim przypadku funkcja zwróci wartość początkową.
Przeciążenie 3:
Trzecie przeciążenie nie jest zbyt przydatne IMO.
To samo można napisać bardziej zwięźle, używając przeciążenia 2, a następnie funkcji, która przekształca jego wynik.
źródło
Aggegate
w .net, które wymagaFunc<T, T, T>
.seed
, stosuje funkcję akumulatora N -1 razy; podczas gdy inne przeciążenia (które mają potrwaćseed
) zastosować funkcję akumulatora N razy.Agregacja jest zasadniczo używana do grupowania lub sumowania danych.
Według MSDN „Funkcja agregująca Stosuje funkcję akumulatora w sekwencji”.
Przykład 1: Dodaj wszystkie liczby do tablicy.
* ważne: Domyślna początkowa wartość zagregowana to 1 element w sekwencji kolekcji. tj .: całkowita wartość początkowa zmiennej domyślnie będzie wynosić 1.
objaśnienie zmiennych
total: przechowuje wartość sumaryczną (wartość zagregowana) zwróconą przez func.
nextValue: jest to kolejna wartość w sekwencji tablicowej. Wartość ta jest następnie dodawana do wartości zagregowanej, tj. Sumy.
Przykład 2: Dodaj wszystkie elementy w tablicy. Ustaw także początkową wartość akumulatora, aby rozpocząć dodawanie od 10.
wyjaśnienie argumentów:
pierwszy argument to wartość początkowa (wartość początkowa, tj. wartość początkowa), która zostanie użyta do rozpoczęcia dodawania z kolejną wartością w tablicy.
drugi argument to func, który wymaga funcji 2 int.
1. suma: będzie to miało miejsce tak samo, jak przed wartością sumaryczną (wartość zagregowana) zwróconą przez func po obliczeniu.
2.nextValue:: to kolejna wartość w sekwencji tablicowej. Wartość ta jest następnie dodawana do wartości zagregowanej, tj. Sumy.
Również debugowanie tego kodu pozwoli lepiej zrozumieć, jak działa agregacja.
źródło
Wiele się nauczyłem z odpowiedzi Jamca .
Jeśli potrzebujesz tylko wygenerować ciąg CSV, możesz spróbować.
Oto test z 1 milionem ciągów
Kod źródłowy jest tutaj
źródło
Oprócz wszystkich świetnych odpowiedzi tutaj, użyłem go również do przejścia przedmiotu przez szereg etapów transformacji.
Jeśli transformacja zostanie zaimplementowana jako a
Func<T,T>
, możesz dodać kilka transformacji doList<Func<T,T>>
i użyć,Aggregate
aby przejść instancjęT
przez każdy krok.Bardziej konkretny przykład
Chcesz wziąć
string
wartość i przeprowadzić szereg transformacji tekstu, które można zbudować programowo.Spowoduje to utworzenie łańcucha przekształceń: Usuń spacje początkowe i końcowe -> usuń pierwszy znak -> usuń ostatni znak -> przekonwertuj na wielkie litery. Kroki w tym łańcuchu można w razie potrzeby dodawać, usuwać lub zmieniać ich kolejność, aby utworzyć wymagany potok transformacji.
Rezultatem tego konkretnego rurociągu jest to, co się
" cat "
dzieje"A"
.To może stać się bardzo potężne, gdy zdasz sobie sprawę, że
T
może to być cokolwiek . Można to wykorzystać do przekształceń obrazu, takich jak filtry, wykorzystującBitMap
jako przykład;źródło
Metoda agregująca jest metodą rozszerzającą dla zbiorów ogólnych. Metoda agregująca stosuje funkcję do każdego elementu kolekcji. Nie tylko stosuje funkcję, ale przyjmuje jej wynik jako wartość początkową dla następnej iteracji. W rezultacie otrzymamy obliczoną wartość (min, maks., Śr. Lub inną wartość statystyczną) ze zbioru.
Dlatego metoda agregująca jest formą bezpiecznej implementacji funkcji rekurencyjnej.
Bezpiecznie , ponieważ rekurencja będzie iterować po każdym elemencie kolekcji i nie możemy uzyskać zawieszenia w nieskończonej pętli z powodu złych warunków wyjścia. Rekurencyjne , ponieważ wynik bieżącej funkcji jest wykorzystywany jako parametr do następnego wywołania funkcji.
Jak to działa:
który robi to samo co ta funkcja:
źródło
To jest wyjaśnienie dotyczące używania
Aggregate
płynnego interfejsu API, takiego jak Sortowanie Linq.i zobaczmy, że chcemy zaimplementować funkcję sortowania, która pobiera zestaw pól, jest to bardzo łatwe w użyciu
Aggregate
zamiast pętli for, jak poniżej:I możemy użyć tego w następujący sposób:
źródło
Wszyscy udzielili wyjaśnień. Moje wyjaśnienie jest takie.
Metoda agregująca stosuje funkcję do każdego elementu kolekcji. Na przykład, miejmy kolekcję {6, 2, 8, 3} i funkcję Dodaj (operator +) robi (((6 + 2) +8) +3) i zwraca 19
W tym przykładzie przekazano nazwaną metodę Add zamiast wyrażenia lambda.
źródło
Krótka i niezbędna definicja może być następująca: metoda rozszerzenia agregacji Linqa pozwala zadeklarować rodzaj funkcji rekurencyjnej zastosowanej do elementów listy, których argumentami są dwa: elementy w kolejności, w jakiej są obecne na liście, jeden element na raz i wynik poprzedniej iteracji rekurencyjnej lub nic, jeśli jeszcze nie rekurencja.
W ten sposób możesz obliczyć silnię liczb lub połączyć łańcuchy.
źródło
Agregat służy do sumowania kolumn w wielowymiarowej tablicy liczb całkowitych
Opcja Select with index jest używana w funkcji Aggregate do sumowania pasujących kolumn i zwracania nowej tablicy; {3 + 2 = 5, 1 + 4 = 5, 7 + 16 = 23, 8 + 5 = 13}.
Ale policzenie liczby prawd w tablicy boolowskiej jest trudniejsze, ponieważ typ skumulowany (int) różni się od typu źródłowego (bool); tutaj ziarno jest konieczne, aby użyć drugiego przeciążenia.
źródło