LINQ Grouping Operators (GroupBy , into)
2022. 2. 7. 00:00ㆍCSharp/Advance
반응형
GroupBy 및 into 연산자는 연산 결과값을 group 화 하여 특정 변수에 저장한다.
기본사용
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
// 각 item 을 5로 나눈 나머지를 g 그룹에 할당
var numberGroups = from n in numbers
group n by n % 5 into g
select (Remainder: g.Key, Numbers: g);
foreach (var g in numberGroups)
{
Console.WriteLine($"Numbers with a remainder of {g.Remainder} when divided by 5:");
foreach (var n in g.Numbers)
{
Console.WriteLine(n);
}
}
// output
Numbers with a remainder of 0 when divided by 5:
5
0
Numbers with a remainder of 4 when divided by 5:
4
9
Numbers with a remainder of 1 when divided by 5:
1
6
Numbers with a remainder of 3 when divided by 5:
3
8
Numbers with a remainder of 2 when divided by 5:
7
2
그룹화 방법
// 제일 앞자리를 key로 그룹화
string[] words = { "blueberry", "chimpanzee", "abacus", "banana", "apple", "cheese" };
var wordGroups = from w in words
group w by w[0] into g
select (FirstLetter: g.Key, Words: g);
foreach (var g in wordGroups)
{
Console.WriteLine("Words that start with the letter '{0}':", g.FirstLetter);
foreach (var w in g.Words)
{
Console.WriteLine(w);
}
}
// output
Words that start with the letter 'b':
blueberry
banana
Words that start with the letter 'c':
chimpanzee
cheese
Words that start with the letter 'a':
abacus
apple
// 속성을 key로 그룹화
List<Product> products = GetProductList();
// 속성을 key로 그룹화
var orderGroups = from p in products
group p by p.Category into g
select (Category: g.Key, Products: g);
foreach (var orderGroup in orderGroups)
{
Console.WriteLine($"Products in {orderGroup.Category} category:");
foreach (var product in orderGroup.Products)
{
Console.WriteLine($"\t{product}");
}
}
// output
Products in Beverages category:
ProductID=1 ProductName=Chai Category=Beverages UnitPrice=$18.00 UnitsInStock=39
ProductID=2 ProductName=Chang Category=Beverages UnitPrice=$19.00 UnitsInStock=17
...
ProductID=76 ProductName=Lakkalikoori Category=Beverages UnitPrice=$18.00 UnitsInStock=57
Products in Condiments category:
ProductID=3 ProductName=Aniseed Syrup Category=Condiments UnitPrice=$10.00 UnitsInStock=13
ProductID=4 ProductName=Chef Anton's Cajun Seasoning Category=Condiments UnitPrice=$22.00 UnitsInStock=53
...
ProductID=77 ProductName=Original Frankfurter grune Soße Category=Condiments UnitPrice=$13.00 UnitsInStock=32
Products in Produce category:
ProductID=7 ProductName=Uncle Bob's Organic Dried Pears Category=Produce UnitPrice=$30.00 UnitsInStock=15
ProductID=14 ProductName=Tofu Category=Produce UnitPrice=$23.25 UnitsInStock=35
...
ProductID=74 ProductName=Longlife Tofu Category=Produce UnitPrice=$10.00 UnitsInStock=4
Products in Meat/Poultry category:
ProductID=9 ProductName=Mishi Kobe Niku Category=Meat/Poultry UnitPrice=$97.00 UnitsInStock=29
ProductID=17 ProductName=Alice Mutton Category=Meat/Poultry UnitPrice=$39.00 UnitsInStock=0
...
ProductID=55 ProductName=Pate chinois Category=Meat/Poultry UnitPrice=$24.00 UnitsInStock=115
Products in Seafood category:
ProductID=10 ProductName=Ikura Category=Seafood UnitPrice=$31.00 UnitsInStock=31
ProductID=13 ProductName=Konbu Category=Seafood UnitPrice=$6.00 UnitsInStock=24
...
ProductID=73 ProductName=Rod Kaviar Category=Seafood UnitPrice=$15.00 UnitsInStock=101
Products in Dairy Products category:
ProductID=11 ProductName=Queso Cabrales Category=Dairy Products UnitPrice=$21.00 UnitsInStock=22
ProductID=12 ProductName=Queso Manchego La Pastora Category=Dairy Products UnitPrice=$38.00 UnitsInStock=86
...
ProductID=72 ProductName=Mozzarella di Giovanni Category=Dairy Products UnitPrice=$34.80 UnitsInStock=14
Products in Confections category:
ProductID=16 ProductName=Pavlova Category=Confections UnitPrice=$17.45 UnitsInStock=29
ProductID=19 ProductName=Teatime Chocolate Biscuits Category=Confections UnitPrice=$9.20 UnitsInStock=25
...
ProductID=68 ProductName=Scottish Longbreads Category=Confections UnitPrice=$12.50 UnitsInStock=6
Products in Grains/Cereals category:
ProductID=22 ProductName=Gustaf's Knackebrod Category=Grains/Cereals UnitPrice=$21.00 UnitsInStock=104
ProductID=23 ProductName=Tunnbrod Category=Grains/Cereals UnitPrice=$9.00 UnitsInStock=61
...
ProductID=64 ProductName=Wimmers gute Semmelknodel Category=Grains/Cereals UnitPrice=$33.25 UnitsInStock=22
중첩 그룹
Order 를 Year 별로 Grouping 한 후 다시 그 안에서 Month 별로 Grouping 하는 예제
List<Customer> customers = GetCustomerList();
var customerOrderGroups = from c in customers
select
(
c.CompanyName,
YearGroups: from o in c.Orders
group o by o.OrderDate.Year into yg
select
(
Year: yg.Key,
MonthGroups: from o in yg
group o by o.OrderDate.Month into mg
select (Month: mg.Key, Orders: mg)
)
);
foreach (var ordersByCustomer in customerOrderGroups)
{
Console.WriteLine($"Customer Name: {ordersByCustomer.CompanyName}");
foreach (var ordersByYear in ordersByCustomer.YearGroups)
{
Console.WriteLine($"\tYear: {ordersByYear.Year}");
foreach (var ordersByMonth in ordersByYear.MonthGroups)
{
Console.WriteLine($"\t\tMonth: {ordersByMonth.Month}");
foreach (var order in ordersByMonth.Orders)
{
Console.WriteLine($"\t\t\tOrder: {order}");
}
}
}
}
// output
Customer Name: Wilman Kala
Year: 1996
Month: 7
Order: 10248: 1996-07-04 for \440.00
Year: 1997
Month: 7
Order: 10615: 1997-07-30 for \120.00
Month: 9
Order: 10673: 1997-09-18 for \412.35
Month: 10
Order: 10695: 1997-10-07 for \642.00
Year: 1998
Month: 2
Order: 10873: 1998-02-06 for \336.80
Order: 10879: 1998-02-10 for \611.30
Order: 10910: 1998-02-26 for \452.90
Month: 4
Order: 11005: 1998-04-07 for \586.00
Customer Name: Wolski Zajazd
Year: 1996
Month: 12
Order: 10374: 1996-12-05 for \459.00
Year: 1997
Month: 7
Order: 10611: 1997-07-25 for \808.00
Month: 12
Order: 10792: 1997-12-23 for \399.85
Year: 1998
Month: 2
Order: 10870: 1998-02-04 for \160.00
Order: 10906: 1998-02-25 for \427.50
Month: 4
Order: 10998: 1998-04-03 for \686.00
Order: 11044: 1998-04-23 for \591.60
사용자 지정 비교자를 사용하여 그룹핑
string[] anagrams = { "from ", " salt", " earn ", " last ", " near ", " form " };
var orderGroups = anagrams.GroupBy(w => w.Trim(), new AnagramEqualityComparer());
foreach (var set in orderGroups)
{
// The key would be the first item in the set
foreach (var word in set)
{
Console.WriteLine(word);
}
Console.WriteLine("...");
}
// 문자의 순서에 상관 없이 같은지 비교 (fo == of)
#region anagram-comparer
public class AnagramEqualityComparer : IEqualityComparer<string>
{
public bool Equals(string x, string y) => getCanonicalString(x) == getCanonicalString(y);
public int GetHashCode(string obj) => getCanonicalString(obj).GetHashCode();
private string getCanonicalString(string word)
{
char[] wordChars = word.ToCharArray();
Array.Sort<char>(wordChars);
return new string(wordChars);
}
}
#endregion
// output
from
form
...
salt
last
...
earn
near
...
관련영상
반응형
'CSharp > Advance' 카테고리의 다른 글
LINQ Aggregator Operators (집계연산자) (0) | 2022.02.09 |
---|---|
Linq 집합 연산자 (Set Operators) (0) | 2022.02.08 |
LINQ 순서정렬 연산자 (OrderBy) (0) | 2022.02.04 |
LINQ Partition 연산자 (Take, Skip) (0) | 2022.02.03 |
LINQ Projection 연산자 (Select) (0) | 2022.02.02 |