본문 바로가기

Develop/.NET 가이드

[C#] LINQ 사용방법 - 그룹 연산자 Group by into

반응형

LINQ
LINQ

그룹연산자 Grouping Operators

그룹연산자는 group by 와 into 키워드를 사용합니다.
그룹 연산자는 입력 시퀀스를 주어진 키에 맞춰 바구니에 나눠 담습니다.

바구니에 나눠담기

numbers 배열 원소를 5로 나누었을 때 나머지 값을 기준으로 나누어 담습니다.

            int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

            var numberGroups = from n in numbers
                               group n by n % 5 into g
                               select (Remainder: g.Key, Numbers: g);

            // numberGroups = {
            //     { 0 : [ 5, 0 ] },
            //     { 4 : [ 4, 9 ] },
            //     { 1 : [ 1, 6 ] },
            //     { 3 : [ 3, 8 ] },
            //     { 2 : [ 7, 2 ] },
            // }

속성 값을 기준으로 바구니에 나눠담기

words 배열 원소를 첫 글자 기준으로 나누어 담습니다.

            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);
            // wordGroups = {
            //     { b : [ "blueberry", "banana" ] },
            //     { c : [ "chimpanzee", "cheese" ] },
            //     { a : [ "abacus", "apple" ] },
            // }

products 리스트를 Category 속성을 기준으로 나누어 담습니다.

            List<Product> products = GetProductList();

            var orderGroups = from p in products
                              group p by p.Category into g
                              select (Category: g.Key, Products: g);

그룹 연산자를 중첩하여 사용하기

            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)
                                                  )
                                      );

IEqualityComparer<T> 구현하여 그룹화하기

먼저 IEqualityComparer<T> 인터페이스를 클래스로 구현합니다.

    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);
        }
    }

구현한 클래스를 GroupBy 메서드에 활용합니다.

            string[] anagrams = { "from   ", " salt", " earn ", "  last   ", " near ", " form  " };

            var orderGroups = anagrams.GroupBy(w => w.Trim(), new AnagramEqualityComparer());

            // orderGroups = {
            //    { from : [ from, form ] },
            //    { salt : [ salt, last ] },
            //    { earn : [ earn, near ] }
            // }

중첩하여 사용할수도 있습니다.

            string[] anagrams = { "from   ", " salt", " earn ", "  last   ", " near ", " form  " };

            var orderGroups = anagrams.GroupBy(
                        w => w.Trim(),
                        a => a.ToUpper(),
                        new AnagramEqualityComparer()
                        );

            // orderGroups = {
            //    { from : [ FROM, FORM ] },
            //    { salt : [ SALT, LAST ] },
            //    { earn : [ EARN, NEAR ] }
            // }
반응형