본문 바로가기
코스웨어/15년 스마트컨트롤러

20150618 4번 김민정LINQ(groupby, join, LINQ를 사용한 성적처리 프로그램)

by 알 수 없는 사용자 2015. 6. 19.
728x90
반응형

20150618 c#

group by로 데이터 분류하기



Group by를 활용한 데이터 분류

- group by는 특정기준으로 데이터를 분류하는 기능을 수행한다.

- 키워드는 group * by * into 이다

- ex) var listprofile = from profile in arrProfile

- group profile by profile.Height < 175 into g

- select new { GroupKey = g.Key, Profiles = g};

 

LINQ의 기본 문법이 부족함으로 보충을 해보자.

LINQ의 기본 키워드는 from, where, oderby, select로 나눈다. 각 키워드의

문법과 세부내용을 학습해보자

 

LINQ 기초 문법

from

- from은 쿼리식의 대상이 되는 데이터 원본과 각 요소 데이터를 나타내는

범위 변수를 지정해 주어야 한다.

이 때 범위 변수는 foreach문에서의 반복 변수와 비슷한데 이 둘의 차이점은

반복 변수는 데이터의 원본으로부터 데이터를 가져와 담아내지만, 범위

변수는 실제로 담아내지 않는다.

- 범위 변수는 데이터 원본이 결정되면 자동적으로 결정됨으로 특별히 신경 쓰지

않아도 된다.

문법은, from * in * 이다.

ex) var result = from n in numbers

where

- where는 필터 역할을 하는 연산자입니다.

 

448p 예제

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Linq;

namespace GroupBy
{
    class Profile
    {
        public string Name { get; set; }
        public int Height { get; set; }
    }

    class MainApp
    {
        static void Main(string[] args)
        {
            Profile[] arrProfile =
            {
                new Profile(){Name="정우성", Height=  186},
                new Profile(){Name="김태희", Height=  158},
                new Profile(){Name="고현정", Height=  172},
                new Profile(){Name="이문세", Height=  178},
                new Profile(){Name="하하", Height=  171}
            };

            var listProfile = from profile in arrProfile
                              orderby profile.Height
                              group profile by profile.Height < 175 into g
                              select new { GroupKey = g.Key, Profiles = g};

            foreach (var Group in listProfile)
            {
                Console.WriteLine("-175cm 미만? : {0}", Group.GroupKey);

                foreach (var profile in Group.Profiles)
                {
                    Console.WriteLine("     {0}, {1}", profile.Name,
                        profile.Height);
                }
            }
        }
    }
}




- groupby는 분류된 자료를 따로 출력해주는 것이 아니라 분류하여 출력하는 기능을

한다.

예제의 코드를 분석

- var listProfile = from profile in arrProfile

- orderby profile.Height

- group profile by profile.Height < 175 into g

- select new { GroupKey = g.Key, Profiles = g };

 

Join

join은 두 데이터 원본을 연결하는 연산이다.

조인에는 내부 조인과 외부조인이 있다.

내부 조인은 두 데이터 원본 사이에서 일치하는 데이터만 연결한 후 반환하는 것이다.

이것은 교집합의 개념과 같다.

문법은 다음과 같다.

- from a in A

join b in B on a.XXXX equals b.YYYY

var listProfile =

from profile in arrProfile

join product in arrProduct on profile.Name equal productStar

select new

{

Name = profile.Name,

Work = product.Title,

Height = profile.Height

};

 

외부 조인은 조인 결과에 기준 되는 데이터 원본은 모두 포함된다는 점을

제외하고는 내부 조인과 같다.

- 문법은 다음과 같다.

- var listProfile =

- from profile in arrProfile

- join product in arrProduct on profile.Name equals product.Star into ps

- from product in ps.DefaultIfEmpty(new Product(){Title="그런거 없음"})

- select new

{

Name = profile.Name,

Work = product.Title,

Height = profile.Height

};

 




 

 

join 예제 p454

using System;
using System.Linq;


namespace join
{
    class Profile
    {
        public string Name { get; set; }
        public int Height { get; set; }

    }
    class Product
    {
        public string Title { get; set; }
        public string Star { get; set; }

    }
    class Program
    {
        static void Main(string[] args)
        {
            Profile[] arrProfile =
            {
                new Profile(){Name="정우성", Height = 186},
                new Profile(){Name="김태희", Height = 158},
                new Profile(){Name="고현정", Height = 172},
                new Profile(){Name="이문세", Height = 178},
                new Profile(){Name="하하", Height = 171}
            };
            Product[] arrProduct = 
            {
                new Product(){Title="비트", Star ="정우성"},
                new Product(){Title="CF 다수", Star ="김태희"},
                new Product(){Title="아이리스", Star ="김태희"},
                new Product(){Title="모래시계", Star ="고현정"},
                new Product(){Title="Solo 예찬", Star ="이문세"},
            };

            var listProfile =
                from profile in arrProfile
                join product in arrProduct on profile.Name equals product.Star
                select new
                {
                    Name = profile.Name,
                    Work = product.Title,
                    Height = profile.Height
                };

            Console.WriteLine("--- 내부 조인 결과 ---");
            foreach (var profile in listProfile)
            {
                Console.WriteLine("이름:{0}, 작품:{1}, 키:{2}cm",
                profile.Name, profile.Work, profile.Height);
            }

            listProfile =
                from profile in arrProfile
                join product in arrProduct on profile.Name equals product.Star into ps
                from product in ps.DefaultIfEmpty(new Product() { Title = "그런거 없음" })
                select new
                {
                    Name = profile.Name,
                    Work = product.Title,
                    Height = profile.Height
                };

            Console.WriteLine();
            Console.WriteLine("--- 외부 조인 결과 ---");
            foreach (var profile in listProfile)
            {
                Console.WriteLine("이름:{0}, 작품:{1}, 키:{2}cm",
                    profile.Name, profile.Work, profile.Height);
            }
        }
    }
}



 

LINQ의 표준 연산자

Quary문은 한 번 설정되면 수정 및 재작성이 잦지 않음으로 개발자들 입장에서는 익숙해지기 어려운 구문이다.


p458예제 SompleLinq2

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Linq;

namespace SimpleLinq2
{
    class Profile
    {
        public string Name { get; set; }
        public int Height { get; set; }
    }

    class MainApp
    {
        static void Main(string[] args)
        {
            Profile[] arrProfile =
            {
                new Profile(){Name="정우성", Height=186},
                new Profile(){Name="김태희", Height=158},
                new Profile(){Name="고현정", Height=172},
                new Profile(){Name="이문세", Height=178},
                new Profile(){Name="하하", Height=171}
            };

            var profiles = arrProfile
                                .Where(profile => profile.Height < 175)
                                .OrderBy(profile => profile.Height)
                                .Select(profile =>
                                new
                                {
                                    Name = profile.Name,
                                    InchHeight = profile.Height * 0.393
                                });

            foreach (var profile in profiles)
                Console.WriteLine("{0}, {1}", profile.Name, profile.InchHeight);
        }
    }
}

 



 

464p 예제 MinMaxAvg

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MinMaxAvg
{
    class Profile
    {
        public string Name { get; set; }
        public int Height { get; set; }
    }

    class MainApp
    {
        static void Main(string[] args)
        {
            Profile[] arrProfile =
            {
                new Profile(){Name="정우성", Height=186},
                new Profile(){Name="김태희", Height=158},
                new Profile(){Name="고현정", Height=172},
                new Profile(){Name="이문세", Height=178},
                new Profile(){Name="하하", Height=171},
            };

            var heightStat = from profile in arrProfile
                             group profile by profile.Height < 175 into g
                             select new
                             {
                                 Group = g.Key == true?"175미만":"175이상",
                                 Count = g.Count(),
                                 Max = g.Max(profile => profile.Height),
                                 Min = g.Min(profile => profile.Height),
                                 Average = g.Average(profile => profile.Height)
                             };

            foreach (var stat in heightStat)
            {
                Console.Write("{0} - Count:{1} Max{2}, "
                    stat.Group, stat.Count, stat.Max);
                Console.WriteLine("Min:{0}, Average:{1}",
                    stat.Min, stat.Average);
            }
        }
    }
}


 

LINQ를 활용한 성적처리 프로그램

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace ConsoleApplication5
{
    class Student
    {
        string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        int math;

        public int Math
        {
            get { return math; }
            set
            {
                if (value < 0 && value > 100)
                {
                    math = 0;
                }
                math = value;
            }
        }
        int science;

        public int Science
        {
            get { return science; }
            set
            {
                if (value < 0 && value > 100)
                {
                    science = 0;
                }
                science = value;
            }
        }
        int english;

        public int English
        {
            get { return english; }
            set
            {
                if (value < 0 && value > 100)
                {
                    english = 0;
                }
                english = value;
            }
        }
        int avg;

        public int Avg
        {
            get { return avg; }
            set { avg = value; }
        }
        public void Show()
        {
            Console.Write("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t", Name, Math, English, Science, (english + math + science), (english + math + science) / 3);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            string name;
            Student std;
            ArrayList arr = new ArrayList();
            while (true)
            {
                Console.Write("이름을입력하세요..하기싫으면 q : ");
                name = Console.ReadLine();
                if (name == "q")
                {
                    break;
                }
                std = new Student();
                std.Name = name;
                Console.Write("수학점수 : ");
                std.Math = int.Parse(Console.ReadLine());
                Console.Write("영어점수 : ");
                std.English = int.Parse(Console.ReadLine());
                Console.Write("과학점수 : ");
                std.Science = int.Parse(Console.ReadLine());
                std.Avg = (std.Math + std.English + std.Science) / 3;
                arr.Add(std);
                Console.WriteLine("입력이완료되었음!!");
            }
            Console.WriteLine("출력");
            Console.WriteLine(" 이름   수학    영어   과학    총점   평균    순위");
            
            var query = 
                from Student student in arr
                orderby student.Avg descending
                select student;
            int c = 1;
            foreach (Student s in query)
            {
                s.Show();
                Console.WriteLine(c);
                c++;
            }
            Console.ReadLine();

            var list1 =
                from Gst in query
                group Gst by Gst.Math > 0 into N
                select new
                {
                    Count = N.Count(),
                    Max = N.Max(Gst => Gst.Math),
                    Min = N.Min(Gst => Gst.Math),
                    Average = N.Average(Gst => Gst.Math)
                };

            foreach(var print in list1)
            {
                Console.WriteLine("Math     :: Highest : {0} | Lowest : {1} | Average : {2}", print.Max,  print.Min,  print.Average);
               
            }

            
            
            var list2 =
                from Gst in query
                group Gst by Gst.English > 0 into N
                select new
                {
                    Count = N.Count(),
                    Max = N.Max(Gst => Gst.English),
                    Min = N.Min(Gst => Gst.English),
                    Average = N.Average(Gst => Gst.English)
                };

            foreach(var print in list2)
            {
                Console.WriteLine("English  :: Highest : {0} | Lowest : {1} | Average : {2}", print.Max,  print.Min,  print.Average);
               
            }

            var list3 =
                from Gst in query
                group Gst by Gst.Science > 0 into N
                select new
                {
                    Count = N.Count(),
                    Max = N.Max(Gst => Gst.Science),
                    Min = N.Min(Gst => Gst.Science),
                    Average = N.Average(Gst => Gst.Science)
                };

                        foreach (var print in list3)
                        {
                            Console.WriteLine("Science  :: Highest : {0} | Lowest : {1} | Average : {2}", print.Max, print.Min, print.Average);

                        }

            
        }
    }
}



728x90