Przetwarzanie kolekcji z Linq to Object cz4
Dzisiaj ostatni odcinek z serii o Linq to object. Opowiem nieco więcej o metodach statystycznych oraz innych dostępnych w linq.
Metody Statystyczne
Metody statystyczne zwracają nam konkretne wartości obliczane na podstawie elementów z kolekcji.
Min, Max
Metody wybierają najmniejszą i największą wartość w naszej kolekcji. Można szeregować elementy po wartościach liczbowych lub jeśli nasz typ implementuje interface IComparable po naszych typach wprost.
1 2 3 |
var numbers = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int minValue = numbers.Min(); int maxValue = numbers.Max(); |
Sum, Average
Metody te potrafią obliczyć sumę oraz średnią wartości liczbowych. W parametrach możemy podać selektor właściwości elementu.
1 2 3 |
var numbers = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int sumValue = numbers.Sum(); double averageValue = numbers.Average(); |
Aggregate
Metoda umożliwiająca agregację danych. W najprostszej formie przyjmuje tylko dwuparametrową funkcję agregującą, gdzie pierwszym parametrem jest agregat a drugim kolejna wartość.
1 2 3 |
var numbers = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // aggregate elements with index weight int aggregate = numbers.Aggregate(new Tuple<int,int>(1,0),(acc, next)=> new Tuple<int, int>(acc.Item1 +1,acc.Item2+(next*acc.Item1)),acc=>acc.Item2); |
Count
Umożliwia policzenie elementów w kolekcji. W postaci bezparametrowej liczy wszystkie elementy, aczkolwiek możemy wprowadzić ograniczenia i policzyć tylko interesujące nas obiekty.
1 2 3 |
var numbers = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int elementsNumber = numbers.Count(); int oddElementsNumber = numbers.Count(n=>n % 2 == 0); |
Any
Przydatna metoda, jeśli chcemy szybko sprawdzić czy kolekcja posiada odpowiednie elementy, bądź elementy w ogóle. Moim zdaniem jest czytelniejsza, gdy chodzi o wykonanie akcji, jeśli w kolekcji są elementy od standardowego przyrównania ilości elementów do zera.
1 2 3 |
var numbers = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; bool anyElement = numbers.Any(); int anyNegativElement = numbers.Any(n => n < 0); |
Przekształcenia kolekcji
Ostatnim elementem jaki chciałbym opisać będą przekształcenia kolekcji, gdzie z jednej kolekcji tworzymy inne.
Concat
Służy do łączenia kolekcji ze sobą. Przy łączeniu kolejność elementów nie zostanie zmieniona a jedynie po zakończeniu pierwszego zbioru w kolekcji dodane zostaną elementy z drugiego zbioru.
1 2 3 |
var numbers = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; var numbers2 = new List<int>() { 6, 7, 8, 9, 10, 11, 14, 5 }; IEnumerable<int> both = numbers.Concat(numbers2); |
Union
Działa podobnie do Concat z tą małą różnicą, iż w wynikowej kolekcji będziemy mieli tylko i wyłącznie unikalne wartości. Można to porównać do wykorzystania łańcucha Concat -> Distinct.
1 2 3 |
var numbers = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; var numbers2 = new List<int>() { 6, 7, 8, 9, 10, 11, 14, 5 }; IEnumerable<int> both = numbers.Union(numbers2); |
GroupBy
Metoda grupująca, umożliwia zgrupowanie elementów. Wynikowo otrzymujemy kolekcję grup, gdzie każda grupa posiada klucz oraz enumerator na kolejne elementy grupy.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public class OrderData { public string ClientId { get; set; } public string ProductId { get; set; } public int Amount { get; set; } } //example var orders = new List<OrderData>(); orders.Add(new OrderData() { ProductId = "prod1", ClientId = "client1", Amount = 3 }); orders.Add(new OrderData() { ProductId = "prod1", ClientId = "client2", Amount = 2 }); orders.Add(new OrderData() { ProductId = "prod1", ClientId = "client3", Amount = 1 }); orders.Add(new OrderData() { ProductId = "prod1", ClientId = "client4", Amount = 3 }); orders.Add(new OrderData() { ProductId = "prod3", ClientId = "client1", Amount = 3 }); orders.Add(new OrderData() { ProductId = "prod2", ClientId = "client1", Amount = 3 }); orders.Add(new OrderData() { ProductId = "prod2", ClientId = "client2", Amount = 3 }); orders.Add(new OrderData() { ProductId = "prod2", ClientId = "client4", Amount = 3 }); var clientGrops = orders.GroupBy(o => o.ClientId, o => o); foreach(var client in clientGrops) { Console.WriteLine(client.Key); foreach (var item in client) { Console.WriteLine($"\t{item.ProductId} {item.Amount}"); } } |
To byłoby tyle na dziś. Opisałem chyba większość metod, z których korzystam na co dzień i które w moim mniemaniu są ważne i warto, żeby je znać. Przykłady wykorzystania jak zwykle na GitHubie https://github.com/Matejkos/BlogProjects/tree/master/LinqObjectOperations