2019년 5월 17일 금요일

Linq 예제 (2)

public class Category
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public override string ToString()
        {
            return "ID :"+ ID +",분야 이름 :" + Name;
        }
    }

    public class Book {
        public string Title { get; set; }
        public int Price { get; set; }
        public int CategoryId { get; set; }
        public int PublishedYear { get; set; }
        public override string ToString()
        {
            return "발행연도 :"+ PublishedYear+", 분야 :"+CategoryId + ", 가격 :"+Price+",제목 :"+Title;
        }
    }

    public static class Library {
        // Categories 속성을 통해 나온 분야의 목록을 구할 수 있다.
        public static IEnumerable<Category> Categories { get; private set; }

        //Books 속성을 통해 위에 나온 서적 정보를 구할 수 있다.
        public static IEnumerable<Book> Books { get; private set; }

        static Library(){
            //Categories와 Books에 데이터를 설정한다. 자세한 구현 내용은 생략
        }
    }





특정 분야 내에서 가장 비싼 가격을 구하는 코드
 
1
2
3
 var price = Library.Books
            .Where(b => b.CategoryId == 1)
            .Max(b => b.Price);
cs



최소값인 요소를 한 개만 구하기

1
2
3
4
5
   var min = Library.Books
                         .Min(x => x.Title.Length);
   var book = Library.Books
                         .First(x => x.Title.Length == min);
cs


평균값 이상인 요소를 모두 구한다.

1
2
3
4
5
6
7
8
9
10
11
12
        var average = Library.Books
                            .Average(x => x.Price);
        var aboves = Library.Books
                            .Where(b => b.Price > average);
        foreach(var x in aboves)
        {
            Debug.Log("x:" + x);
        }
cs


중복제거

1
2
3
4
5
6
7
8
9
10
11
12
13
처음 Select 메서드로 발행연도만 구하고 distinct 메서드로 중복을 제거하고 마지막에 OrderBy 메서드로 정렬합니다.
        var query = Library.Books
                            .Select(b => b.PublishedYear)
                            .Distinct()
                            .OrderBy(y => y);
        foreach (var n in query)
        {
            Debug.Log("발행연도 :" + n);
        }
cs


여러 개의 키로 나열한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
여러 개의 키로 나열하려면 OrderBy 또는 OrderByDescending 메서드 뒤에 ThenBy 메서드 나 ThenByDescening 메서드를 호출합니다.
        var books = Library.Books
                            .OrderBy(b => b.CategoryId)
                            .ThenByDescending(b => b.PublishedYear);
        foreach(var x in books)
        {
            Debug.Log("xxxx :" + x);
        }
위의 코드에서는 CategoryId, PublishedYear라는 순서로 나열했습니다. PublishedYear는 ThenByDescending 메서드로 정렬했으므로 최신 발행연도부터 표시됩니다.
cs


여러 요소 가운데 어느 하나에 해당하는 객체를 구한다.


1
2
3
        var years = new int[] { 20132016 };
        var books = Library.Books
                            .Where(b => years.Contains(b.PublishedYear));
cs



GroupBy 메서드로 그룹화한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
GroupBy 메서드를 사용하면 지정한 키마다 요소를 그룹화할 수 있습니다.
발행연도를 기준으로 서적을 그룹화하는 예를 살펴보겠습니다.
        //발행연도를 기준으로 그룹화한다.
        var groups = Library.Books
                            .GroupBy(b => b.PublishedYear)
                            .OrderBy(g => g.Key);
       
        // key가 PublishedYear인 Dictionary생성됨
        //IEnumerable<IGrouping<int,Book>>
        foreach (var g in groups)
        {
            Debug.Log("년:" + g.Key);
            foreach (var book in g)
            {
                Debug.Log(" " + book);
            }
        }
cs


각 그룹에서 최댓값을 가진 객체를 구한다.


1
2
3
4
5
6
7
8
9
10
  //각 발행연도 그룹에서 가장 가격이 비싼 서적을 구한다.
        var selected = Library.Books
                                .GroupBy(x => x.PublishedYear)
                                .Select(b => b.OrderByDescending(a => a.Price).First())
                                .OrderBy(o => o.PublishedYear);
        foreach (var book in selected)
        {
            Debug.Log(book.PublishedYear + "년 제목:" + book.Title + "가격 :" + book.Price);
        }
cs



ToLookup으로 발행연도별로 그룹화한다.
1
2
3
4
5
6
7
8
9
10
11
        var lookup = Library.Books
                            .ToLookup(x => x.PublishedYear);
        var books = lookup[2014];//키를 PublishedYear로 가지는
        foreach (var b in books)
        {
            Debug.Log("book :" + b);
        }
cs


join메서드


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
30
31
32
        //Books 와 Categories를 분야 ID로 결합한다
        var books = Library.Books
                           .OrderBy(b => b.CategoryId)
                           .ThenBy(b => b.PublishedYear)
                           .Join(Library.Categories,
                                book => book.CategoryId,
                                category => category.ID,
                                (book, category) => new
                                {
                                    Title = book.Title,
                                    Category = category.Name,
                                    PublishedYear = book.PublishedYear,
                                }
                           );
        foreach (var book in books)
        {
            Debug.Log(book.PublishedYear + "년 제목:" + book.Title + "카테고리 :" + book.Category);
        }
        //join 메서드가 받는 네 개의 인수는 다음과 같다.
        //첫 번째 인수: 결합할 두 번째 시퀀스
        //두 번째 인수: 대상 시퀀스의 결합에 사용할 키
        //세 번째 인수: 두 번째 시퀀스의 결합에 사용할 키
        //네 번째 인수: 결합한 결과로 얻어지는 객체를 생성하는 함수
cs


2016년에 발행된 분야의 목록을 구한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        var names = Library.Books
                            .Where(b => b.PublishedYear == 2016)
                            .Join(Library.Categories,
                                book => book.CategoryId,
                                category => category.ID,
                                (book, category) => category.Name)
                            .Distinct();
        foreach (var name in names)
        {
            Debug.Log(name);
        }
        //일단 where 메서드로 2016년에 발행된 서적만 골라냅니다. 이렇게 골라낸 서적의 목록과 분야의 목록을 join 메서드로 결합합니다.
        //구하는것은 이름 뿐이므로 마지막 인수에는 category의 name속성만 반환하는 람다식을 넘겨줍니다.
        //마지막에는 Distinct로 중복제거
cs


 GroupJoin으로 그룹화해서 결합한다.


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
        var groups = Library.Categories
                            .GroupJoin(Library.Books,
                            c => c.ID,
                            b => b.CategoryId,
                            (c, b) => new
                            {
                                Category = c.Name,
                                Books = b,
                            });
        foreach (var group in groups)
        {
            Debug.Log(group.Category);
            foreach (var book in group.Books)
            {
                Debug.Log("title :" + book.Title + "발행년도 :" + book.PublishedYear);
            }
        }
//join 메서드와 차이점은 결과가 2차원의 표 형식이 되는 것이 아니고 분야 아래에
여러 서적이 늘어서는 계층 형식으로 결합된다 라는점입니다.
cs




댓글 없음:

댓글 쓰기

git rejected error(feat. cherry-pick)

 문제 아무 생각 없이 pull을 받지않고 로컬에서 작업! 커밋, 푸시 진행을 해버렷다. push에선 remote와 다르니 당연히 pull을 진행해라고 하지만 로컬에서 작업한 내용을 백업하지 않고 진행하기에는 부담스럽다(로컬작업 유실 가능성) 해결하려...