newind2000 2015. 6. 18. 13:28

================================ Outline ====================================

LINQ

- groupby

- 기초문법

- join

- 표준연산자

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

----------------------------------------------------------------------------

 

LINQ 

 

[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는 필터 역할을 하는 연산자입니다.

 

 

교재 p/449 GroupBy 예제,


using System;
using System.Linq;

namespace _20150618
{
    class Profile
    {
        public string Name { get; set; }
        public int Height { 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}
            };

            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

};

 

 

교재 p/454 조인 예제,

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

 

 

교재 p/464 LINQ의 표준 연산자 예제,




using System;
using System.Linq;

namespace MinMaxAvg
{
    class Profile
    {
        public string Name { get; set; }
        public int Height { 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}

            };

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

                        }

            
        }
    }
}



반응형