블로그 이미지
따시쿵

calendar

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

Notice

2015. 6. 19. 17:18 C# with LINQ to SQL

앞 부분에 이어서 계속 그룹화 시키는 방법을 알아 보도록 하겠습니다. StudentClass 클래스와 데이타를 모두 같이 사용합니다.

 

예제1 - 숫자 범위를 그룹키로 사용하는 경우

 

다음 예제에서는 숫자 범위를 그룹 키로 사용하여 그룹화하는 방법을 보여 줍니다. 쿼리는 FirstName, LastName 과 학생이 속한 백분위수 범위만 포함한 Anonymous type(익명 타입)으로 결과를 반환합니다.

 

결과를 표시하기 위해 완전한 Student 개체를 사용할 필요가 없으므로 익명 형식이 사용됩니다.

GetPercentile은 학생의 평균 점수에 기초하여 백분위수를 계산하는 함수입니다. 이 메서드는 0에서 10 사이의 정수를 반환합니다.

        protected static int GetPercentile(Student s)
        {
            double avg = s.ExamScores.Average();
            return avg > 0 ? (int)avg / 10 : 0;
        }

 

참고로 List<T> 형식의 데이타에서 평균값을 구하는 method 가 Average() 입니다. 최고값은 Max(), 최저값은 Min(), 아이템 개수는 Count() 입니다.

 

어째든, 다음 함수가 실제적으로 그룹화를 시키는 내용입니다.

        public void GroupByRange()
        {
            Console.WriteLine("\r\n숫자 범위로 그룹화 시키기:");

            var queryNumericRange =
                from student in students
                let percentile = GetPercentile(student)
                group new { student.FirstName, student.LastName } by percentile into percentGroup
                orderby percentGroup.Key
                select percentGroup;

            // Nested foreach required to iterate over groups and group items. 
            foreach (var studentGroup in queryNumericRange)
            {
                Console.WriteLine("Key: {0}", (studentGroup.Key * 10));
                foreach (var item in studentGroup)
                {
                    Console.WriteLine("\t{0}, {1}", item.LastName, item.FirstName);
                }
            }
        }

 

전체 소스

    public class StudentClass
    {
        #region data
        protected enum GradeLevel { FirstYear = 1, SecondYear, ThirdYear, FourthYear };
        protected class Student
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public int ID { get; set; }
            public GradeLevel Year;
            public List<int> ExamScores;
        }

        protected static List<string> students = new List<string>
        {
            new Student {FirstName = "Terry", LastName = "Adams", ID = 120, Year = GradeLevel.SecondYear, ExamScores = new List<int>{ 99, 82, 81, 79}},
            new Student {FirstName = "Fadi", LastName = "Fakhouri", ID = 116, Year = GradeLevel.ThirdYear,ExamScores = new List<int>{ 99, 86, 90, 94}},
            new Student {FirstName = "Hanying", LastName = "Feng", ID = 117, Year = GradeLevel.FirstYear, ExamScores = new List<int>{ 93, 92, 80, 87}},
            new Student {FirstName = "Cesar", LastName = "Garcia", ID = 114, Year = GradeLevel.FourthYear,ExamScores = new List<int>{ 97, 89, 85, 82}},
            new Student {FirstName = "Debra", LastName = "Garcia", ID = 115, Year = GradeLevel.ThirdYear, ExamScores = new List<int>{ 35, 72, 91, 70}},
            new Student {FirstName = "Hugo", LastName = "Garcia", ID = 118, Year = GradeLevel.SecondYear, ExamScores = new List<int>{ 92, 90, 83, 78}},
            new Student {FirstName = "Sven", LastName = "Mortensen", ID = 113, Year = GradeLevel.FirstYear, ExamScores = new List<int>{ 88, 94, 65, 91}},
            new Student {FirstName = "Claire", LastName = "O'Donnell", ID = 112, Year = GradeLevel.FourthYear, ExamScores = new List<int>{ 75, 84, 91, 39}},
            new Student {FirstName = "Svetlana", LastName = "Omelchenko", ID = 111, Year = GradeLevel.SecondYear, ExamScores = new List<int>{ 97, 92, 81, 60}},
            new Student {FirstName = "Lance", LastName = "Tucker", ID = 119, Year = GradeLevel.ThirdYear, ExamScores = new List<int>{ 68, 79, 88, 92}},
            new Student {FirstName = "Michael", LastName = "Tucker", ID = 122, Year = GradeLevel.FirstYear, ExamScores = new List<int>{ 94, 92, 91, 91}},
            new Student {FirstName = "Eugene", LastName = "Zabokritski", ID = 121, Year = GradeLevel.FourthYear, ExamScores = new List<int>{ 96, 85, 91, 60}}
        };
        #endregion

        //Helper method, used in GroupByRange. 
        protected static int GetPercentile(Student s)
        {
            double avg = s.ExamScores.Average();
            return avg > 0 ? (int)avg / 10 : 0;
        }
        #region GroupByRange
        public void GroupByRange()
        {
            Console.WriteLine("\r\n숫자 범위로 그룹화 시키기:");

            var queryNumericRange =
                from student in students
                let percentile = GetPercentile(student)
                group new { student.FirstName, student.LastName } by percentile into percentGroup
                orderby percentGroup.Key
                select percentGroup;

            // Nested foreach required to iterate over groups and group items. 
            foreach (var studentGroup in queryNumericRange)
            {
                Console.WriteLine("Key: {0}", (studentGroup.Key * 10));
                foreach (var item in studentGroup)
                {
                    Console.WriteLine("\t{0}, {1}", item.LastName, item.FirstName);
                }
            }
        }
        #endregion
    }

    class Program
    {
        static void Main(string[] args)
        {
            StudentClass sc = new StudentClass();
            sc.GroupByRange();

            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
    }

 

예제2 - 비교 연산자를 이용하여 그룹화 시키는 방법

 

다음 예제에서는 부울 비교 식을 사용하여 소스 요소를 그룹화하는 방법을 보여 줍니다.

 

이 예제에서 부울 식은 학생의 평균 시험 점수가 75점을 넘는지 확인합니다. 위의 예제와 같이 완전한 소스 요소가 필요하지 않으므로 결과는 익명 형식으로 반환됩니다. 익명 형식의 속성은 Key 멤버의 속성이 되고 쿼리 실행 시에 이름으로 액세스할 수 있습니다.

 

결론은 평균 점수가 75점을 넘는지,못 넘는지를 넘는지를 기준으로 두 그룹으로 나뉘는 쿼리문입니다. 비교의 기준은 by 절에 있는 by student.ExamScores.Average() > 75 절입니다.

public void GroupByBoolean()
{            
    Console.WriteLine("\r\nGroup by a Boolean into two groups with string keys");
    Console.WriteLine("\"True\" and \"False\" and project into a new anonymous type:");
    var queryGroupByAverages = from student in students
                               group new { student.FirstName, student.LastName }
                                    by student.ExamScores.Average() > 75 into studentGroup
                               select studentGroup;

    foreach (var studentGroup in queryGroupByAverages)
    {
        Console.WriteLine("Key: {0}", studentGroup.Key);
        foreach (var student in studentGroup)
            Console.WriteLine("\t{0} {1}", student.FirstName, student.LastName);
    }            
}

 

전체 소스

    public class StudentClass
    {
        #region data
        protected enum GradeLevel { FirstYear = 1, SecondYear, ThirdYear, FourthYear };
        protected class Student
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public int ID { get; set; }
            public GradeLevel Year;
            public List<int> ExamScores;
        }

        protected static List<Student> students = new List<Student>
        {
            new Student {FirstName = "Terry", LastName = "Adams", ID = 120, Year = GradeLevel.SecondYear, ExamScores = new List<int>{ 99, 82, 81, 79}},
            new Student {FirstName = "Fadi", LastName = "Fakhouri", ID = 116, Year = GradeLevel.ThirdYear,ExamScores = new List<int>{ 99, 86, 90, 94}},
            new Student {FirstName = "Hanying", LastName = "Feng", ID = 117, Year = GradeLevel.FirstYear, ExamScores = new List<int>{ 93, 92, 80, 87}},
            new Student {FirstName = "Cesar", LastName = "Garcia", ID = 114, Year = GradeLevel.FourthYear,ExamScores = new List<int>{ 97, 89, 85, 82}},
            new Student {FirstName = "Debra", LastName = "Garcia", ID = 115, Year = GradeLevel.ThirdYear, ExamScores = new List<int>{ 35, 72, 91, 70}},
            new Student {FirstName = "Hugo", LastName = "Garcia", ID = 118, Year = GradeLevel.SecondYear, ExamScores = new List<int>{ 92, 90, 83, 78}},
            new Student {FirstName = "Sven", LastName = "Mortensen", ID = 113, Year = GradeLevel.FirstYear, ExamScores = new List<int>{ 88, 94, 65, 91}},
            new Student {FirstName = "Claire", LastName = "O'Donnell", ID = 112, Year = GradeLevel.FourthYear, ExamScores = new List<int>{ 75, 84, 91, 39}},
            new Student {FirstName = "Svetlana", LastName = "Omelchenko", ID = 111, Year = GradeLevel.SecondYear, ExamScores = new List<int>{ 97, 92, 81, 60}},
            new Student {FirstName = "Lance", LastName = "Tucker", ID = 119, Year = GradeLevel.ThirdYear, ExamScores = new List<int>{ 68, 79, 88, 92}},
            new Student {FirstName = "Michael", LastName = "Tucker", ID = 122, Year = GradeLevel.FirstYear, ExamScores = new List<int>{ 94, 92, 91, 91}},
            new Student {FirstName = "Eugene", LastName = "Zabokritski", ID = 121, Year = GradeLevel.FourthYear, ExamScores = new List<int>{ 96, 85, 91, 60}}
        };
        #endregion

        //Helper method, used in GroupByRange. 
        protected static int GetPercentile(Student s)
        {
            double avg = s.ExamScores.Average();
            return avg > 0 ? (int)avg / 10 : 0;
        }

        #region GroupByBoolean
        public void GroupByBoolean()
        {
            Console.WriteLine("\r\nGroup by a Boolean into two groups with string keys");
            Console.WriteLine("\"True\" and \"False\" and project into a new anonymous type:\n");
            var queryGroupByAverages = from student in students
                                       group new { student.FirstName, student.LastName }
                                            by student.ExamScores.Average() > 75 into studentGroup
                                       select studentGroup;

            foreach (var studentGroup in queryGroupByAverages)
            {
                Console.WriteLine("Key: {0}", studentGroup.Key);

                foreach (var student in studentGroup)
                    Console.WriteLine("\t{0} {1}", student.FirstName, student.LastName);
            }
        }
        #endregion
    }

    class Program
    {
        static void Main(string[] args)
        {
            StudentClass sc = new StudentClass();
            sc.GroupByBoolean();

            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
    }

 

posted by 따시쿵
2015. 6. 18. 10:44 C# with LINQ to SQL

이번 포스트에서는 Group by 로 데이타 분류하기를 다뤄보도록 하겠습니다.

 

기본 문법

 

group A by B into C

 

A 에는 from 절에서 뽑아낸 범위 범수  

B 에는 분류 기준

C 에는 그룹 변수를 위치 시킵니다.

 

 

예제1

 

학생들의 점수를 나타내는 클래스를 대상으로 80점 미만인가? 80점 이상인가를 group by 절을 이용해서 작성해 보도록 하겠습니다.

    class Profile
    {
        public string Name { get; set; }
        public int Score { get; set; }
    }

    Profile[] arrProflie = {
                                new Profile(){Name="이순신",    Score=65},
                                new Profile(){Name="을지문덕",  Score=88},
                                new Profile(){Name="강감찬",    Score=79},
                                new Profile(){Name="세종대왕",  Score=59},
                                new Profile(){Name="장영실",    Score=90}
                            };

 

이 데이타를 group by 절을 이용해서 분류해 보겠습니다.

    var listProfile = from profile in arrProflie
                      orderby profile.Score
                      group profile by profile.Score < 80 into g
                      select new { GroupKey = g.Key, Profiles = g };

 

위의 쿼리식의 그룹 변수 g에는 Score 값이 80점 미만인 객체의 컬렉션, 80점 이상인 객체의 컬렉센이 입력되고, select 문이 추출하는 새로운 무명 향식은 컬렉션의 컬렉션이 됩니다. 그리고 이 무명형식의 Profiles 필드는 바로 이 그룹 변수 g를 담게 됩니다. 정렬은 점수 오름차순입니다. 최종적으로 쿼리의 결과를 다담은 listProfiles은 다음과 같은 모습을 할 것입니다.

 

 

전체 소스

    class Profile
    {
        public string Name { get; set; }
        public int Score { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Profile[] arrProflie = {
                                        new Profile(){Name="이순신",    Score=65},
                                        new Profile(){Name="을지문덕",  Score=88},
                                        new Profile(){Name="강감찬",    Score=79},
                                        new Profile(){Name="세종대왕",  Score=59},
                                        new Profile(){Name="장영실",    Score=90}
                                    };

            var listProfile = from profile in arrProflie
                              orderby profile.Score
                              group profile by profile.Score < 80 into g
                              select new { GroupKey = g.Key, Profiles = g };

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

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

                Console.WriteLine();
            }

            Console.ReadLine();
        }
    }

 

 

 

예제2 -  단일 속성을 그룹키로 사용하여 그룹화 시키기

 

학년별 학생들의 점수를 표시하기 위해 StudentClass 를 정의 합니다. 그리고 데이타도 같이 추가해 줍니다.

    public class StudentClass
    {
        #region data
        protected enum GradeLevel { FirstYear = 1, SecondYear, ThirdYear, FourthYear };
        protected class Student
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public int ID { get; set; }
            public GradeLevel Year;
            public List<int> ExamScores;
        }

        protected static List<Student> = new List<Student>
        {
            new Student {FirstName = "Terry", LastName = "Adams", ID = 120, Year = GradeLevel.SecondYear, ExamScores = new List<int>{ 99, 82, 81, 79}},
            new Student {FirstName = "Fadi", LastName = "Fakhouri", ID = 116, Year = GradeLevel.ThirdYear,ExamScores = new List<int>{ 99, 86, 90, 94}},
            new Student {FirstName = "Hanying", LastName = "Feng", ID = 117, Year = GradeLevel.FirstYear, ExamScores = new List<int>{ 93, 92, 80, 87}},
            new Student {FirstName = "Cesar", LastName = "Garcia", ID = 114, Year = GradeLevel.FourthYear,ExamScores = new List<int>{ 97, 89, 85, 82}},
            new Student {FirstName = "Debra", LastName = "Garcia", ID = 115, Year = GradeLevel.ThirdYear, ExamScores = new List<int>{ 35, 72, 91, 70}},
            new Student {FirstName = "Hugo", LastName = "Garcia", ID = 118, Year = GradeLevel.SecondYear, ExamScores = new List<int>{ 92, 90, 83, 78}},
            new Student {FirstName = "Sven", LastName = "Mortensen", ID = 113, Year = GradeLevel.FirstYear, ExamScores = new List<int>{ 88, 94, 65, 91}},
            new Student {FirstName = "Claire", LastName = "O'Donnell", ID = 112, Year = GradeLevel.FourthYear, ExamScores = new List<int>{ 75, 84, 91, 39}},
            new Student {FirstName = "Svetlana", LastName = "Omelchenko", ID = 111, Year = GradeLevel.SecondYear, ExamScores = new List<int>{ 97, 92, 81, 60}},
            new Student {FirstName = "Lance", LastName = "Tucker", ID = 119, Year = GradeLevel.ThirdYear, ExamScores = new List<int>{ 68, 79, 88, 92}},
            new Student {FirstName = "Michael", LastName = "Tucker", ID = 122, Year = GradeLevel.FirstYear, ExamScores = new List<int>{ 94, 92, 91, 91}},
            new Student {FirstName = "Eugene", LastName = "Zabokritski", ID = 121, Year = GradeLevel.FourthYear, ExamScores = new List<int>{ 96, 85, 91, 60}}
        };
        #endregion
    }

 

예제에서는 학생들의 LastName 을 키로 사용합니다. 또한 부분 문자열을 키로 사용할 수도 있습니다. 그룹화 작업은 형식에 대해 같은 연산자(equal, ==)를 사용합니다.

 

아래는 실제로 그룹화 작업을 수행하는 method 입니다. Group의 변수는 IGroup<T> 형식입니다.

        public void GroupBySingleProperty()
        {
            Console.WriteLine("Group by a single property in an object:\n");

            // Variable queryLastNames is an IEnumerable<IGROUPING<string, DataClass.Student>>.  
            var queryLastNames =
                from student in students
                group student by student.LastName into newGroup
                orderby newGroup.Key
                select newGroup;

            foreach (var nameGroup in queryLastNames)
            {
                Console.WriteLine("Key: {0}", nameGroup.Key);
                foreach (var student in nameGroup)
                {
                    Console.WriteLine("\t{0}, {1}", student.LastName, student.FirstName);
                }
            }
        }

 

전체 소스

    public class StudentClass
    {
        #region data
        protected enum GradeLevel { FirstYear = 1, SecondYear, ThirdYear, FourthYear };
        protected class Student
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public int ID { get; set; }
            public GradeLevel Year;
            public List<int> ExamScores;
        }

        protected static List<Student> students = new List<Student>
        {
            new Student {FirstName = "Terry", LastName = "Adams", ID = 120, Year = GradeLevel.SecondYear, ExamScores = new List<int>{ 99, 82, 81, 79}},
            new Student {FirstName = "Fadi", LastName = "Fakhouri", ID = 116, Year = GradeLevel.ThirdYear,ExamScores = new List<int>{ 99, 86, 90, 94}},
            new Student {FirstName = "Hanying", LastName = "Feng", ID = 117, Year = GradeLevel.FirstYear, ExamScores = new List<int>{ 93, 92, 80, 87}},
            new Student {FirstName = "Cesar", LastName = "Garcia", ID = 114, Year = GradeLevel.FourthYear,ExamScores = new List<int>{ 97, 89, 85, 82}},
            new Student {FirstName = "Debra", LastName = "Garcia", ID = 115, Year = GradeLevel.ThirdYear, ExamScores = new List<int>{ 35, 72, 91, 70}},
            new Student {FirstName = "Hugo", LastName = "Garcia", ID = 118, Year = GradeLevel.SecondYear, ExamScores = new List<int>{ 92, 90, 83, 78}},
            new Student {FirstName = "Sven", LastName = "Mortensen", ID = 113, Year = GradeLevel.FirstYear, ExamScores = new List<int>{ 88, 94, 65, 91}},
            new Student {FirstName = "Claire", LastName = "O'Donnell", ID = 112, Year = GradeLevel.FourthYear, ExamScores = new List<int>{ 75, 84, 91, 39}},
            new Student {FirstName = "Svetlana", LastName = "Omelchenko", ID = 111, Year = GradeLevel.SecondYear, ExamScores = new List<int>{ 97, 92, 81, 60}},
            new Student {FirstName = "Lance", LastName = "Tucker", ID = 119, Year = GradeLevel.ThirdYear, ExamScores = new List<int>{ 68, 79, 88, 92}},
            new Student {FirstName = "Michael", LastName = "Tucker", ID = 122, Year = GradeLevel.FirstYear, ExamScores = new List<int>{ 94, 92, 91, 91}},
            new Student {FirstName = "Eugene", LastName = "Zabokritski", ID = 121, Year = GradeLevel.FourthYear, ExamScores = new List<int>{ 96, 85, 91, 60}}
        };
        #endregion

        //Helper method, used in GroupByRange. 
        protected static int GetPercentile(Student s)
        {
            double avg = s.ExamScores.Average();
            return avg > 0 ? (int)avg / 10 : 0;
        }        

        public void QueryHighScores(int exam, int score)
        {
            var highScores = from student in students
                             where student.ExamScores[exam] > score
                             select new { Name = student.FirstName, Score = student.ExamScores[exam] };

            foreach (var item in highScores)
            {
                Console.WriteLine("{0,-15}{1}", item.Name, item.Score);
            }
        }

        public void GroupBySingleProperty()
        {
            Console.WriteLine("single property[LastName] 로 그룹화 시키기:\n");

            // Variable queryLastNames is an IEnumerable<IGrouping<string,  
            // DataClass.Student>>.  
            var queryLastNames =
                from student in students
                group student by student.LastName into newGroup
                orderby newGroup.Key
                select newGroup;

            foreach (var nameGroup in queryLastNames)
            {
                Console.WriteLine("Key: {0}", nameGroup.Key);
                foreach (var student in nameGroup)
                {
                    Console.WriteLine("\t{0}, {1}", student.LastName, student.FirstName);
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            StudentClass sc = new StudentClass();
            sc.GroupBySingleProperty();

            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
    }

 

 

 

예제3 - 개체의 속성(property)이 아닌 항목을 그룹 키로 사용하는 경우

 

위에서 사용한 StudentClass 를 계속 사용합니다.

 

이 예제에서 키는 학생의 LastName 중에서 첫 번째 문자입니다. 첫번째 문자를 가지고 그룹화를 시키는 method 는 아래와 같습니다.

        public void GroupBySubstring()
        {
            Console.WriteLine("\r\nLastName 의 첫글자를 가지고 그룹화 사키기:");

            var queryFirstLetters =
                from student in students
                group student by student.LastName[0] into newGroup
                orderby newGroup.Key
                select newGroup;

            foreach (var studentGroup in queryFirstLetters)
            {
                Console.WriteLine("Key: {0}", studentGroup.Key);
                // Nested foreach is required to access group items. 
                foreach (var student in studentGroup)
                {
                    Console.WriteLine("\t{0}, {1}", student.LastName, student.FirstName);
                }
            }
        }

 

 

posted by 따시쿵
2015. 6. 16. 10:49 C# with LINQ to SQL

LINQ 는 Language INtegrated Query위 약어로, 컬렉션을 편리하게 다루기 위한 목적으로 만들어진 질의 언어입니다. C# 3.0 버전에서부터 탑재한 LINQ 덕분에 프로그래머들은 데이타를 찾고 병합하고 정렬하는 코드를 작성하는 짐을 상당 부분 내려 놓을 수 있게 되었습니다.

 

기본 문법

 

  • From : 어떤 데이타 집합에서 찾을 것인가?
  • Where : 어떤 값의 데이타를 찾을 것인가? (필터 역할)
  • Orderby : 어떤 데이타 순서대로 나열할 것인가?(순서 정하기)
  • Select : 어떤 항목을 추출할 것인가?

 

예제 1 - LINQ 문을 사용하지 않고 프로그램 작성

 

키가 175 미만인 데이타만을 골라서 새 컬렉션으로 추출하는 프로그램

    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=210},
                                       new Profile{Name = "강감찬", Height=169},
                                       new Profile{Name = "을지문덕", Height=175},
                                       new Profile{Name = "세종대왕", Height=183},
                                       new Profile{Name = "안창호", Height=159},
                                       new Profile{Name = "연개소문", Height=172}
                                   };

            // 1단계 - 키가 175 미만인 데이타를 추출함
            List<profile> profiles = new List<Profile>();
            foreach(Profile profile in arrProfile)
            {
                if (profile.Height < 175)
                    profiles.Add(profile);
            }

            // 2단계 - 키의 오름차순으로 정열함
            profiles.Sort(
                (profile1, profile2) =>  { return profile1.Height - profile2.Height;  }
            );

            // 3단계 - 출력함
            foreach(var profile in profiles)
                Console.WriteLine("{0}, {1}", profile.Name, profile.Height);

            Console.ReadLine();
        }
    }

 

 

예제 2 - LINQ 문을 사용하여 프로그램 작성

 

키가 175 미만인 데이타만을 골라서 새 컬렉션으로 추출하는 프로그램

    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=210},
                                       new Profile{Name = "강감찬", Height=169},
                                       new Profile{Name = "을지문덕", Height=175},
                                       new Profile{Name = "세종대왕", Height=183},
                                       new Profile{Name = "안창호", Height=159},
                                       new Profile{Name = "연개소문", Height=172}
                                   };

            // 1단계 - 키가 175 미만인 데이타를 추출함
            var profiles = from profile in arrProfile
                           where profile.Height < 175
                           orderby profile.Height ascending
                           select profile;

            // 2단계 - 출력함
            foreach (var profile in profiles)
                Console.WriteLine("{0}, {1}", profile.Name, profile.Height);

            Console.ReadLine();
        }
    }


예제3 - select 문의 분석


select 절은 다음과 같이 사용하면 됩니다.

var profiles = from profile in arrProfile
            where profile.Height < 175
            orderby profile.Height ascending
            select profile;

위의 예에서 var 형식으로 선언된 profiles 의 실제 형식이 궁금할 겁니다. C# 컴파일러가 var 형식을 LINQ 쿼리식이 반환할 결과 형식에 맞춰 알아서 컴파일 해 주기는 하지만, 실제로 var 가 어떤 형식으로 치환되는지를 알아둘 필요가 있습니다. LINQ 질의 결과는 IEnumerable<T> 로 치환되는데, 이 형식 매개변수 T는 select 문에 의해 결정됩니다. 


예를 들어 위 LINQ 쿼리식은 배열로부터 175 미만인 Profile 객체를 골라내는데, 그 결과는 IEnumerable<Profile> 형식이 됩니다. 다음과 같이 select 문에서 Profile 객체 전체가 아닌 Name 프로퍼티만 추출하면 profiles는 IEnumerable<string> 형식으로 컴파일됩니다.

var profiles = from profile in arrProfile
            where profile.Height < 175
            orderby profile.Height ascending
            select profile.Name;

추가적으로 select 문은 무명 형식(Anonymous type)을 이용해서 다음과 같이 새로운 형식을 만들어 낼 수도 있습니다.

var profiles = from profile in arrProfile
            where profile.Height < 175
            orderby profile.Height ascending
            select new { Name = profile.Name, InchHeight = profile.Height * 0.393 };

전체 소스

    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=210},
                                       new Profile{Name = "강감찬", Height=169},
                                       new Profile{Name = "을지문덕", Height=175},
                                       new Profile{Name = "세종대왕", Height=183},
                                       new Profile{Name = "안창호", Height=159},
                                       new Profile{Name = "연개소문", Height=172}
                                   };

            // 1단계 - 키가 175 미만인 데이타를 추출함
            var profiles = from profile in arrProfile
                           where profile.Height < 175
                           orderby profile.Height ascending
                           select new { Name = profile.Name, InchHeight = profile.Height * 0.393 };

            // 2단계 - 출력함
            foreach (var profile in profiles)
                Console.WriteLine("{0}, {1}", profile.Name, profile.InchHeight);

            Console.ReadLine();
        }
    }



 

예제4 - where 조건에 and, or 연산자 사용하기 / 여러개의 데이타 원본에 질의하기

 

LINQ 쿼리식은 데이타 원본에 접근하기 위해 from 절을 사용합니다. 여러개의 데이타 원본에 접근하려면 from 절을 중첩해서 사용하면 됩니다.

 

foreach 문을 중첩해서 사용하는 것처럼 말입니다.

 

다음의 클래스는 각 학년별, 학급별, 점수를 나타내며, 과목별 점수를 담기 위해 Score 필드를 배열로 선언했습니다.

    class GradeClassScore
    {
        public int Grade { get; set; }
        public string ClassName { get; set; }
        public int[] Score { get; set; }
    }

 

그리고 이 클래스를 바탕으로 배열 하나를 다음과 같이 선언했습니다.

            GradeClassScore[] arrClass = {
                                             new GradeClassScore(){Grade = 1, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}},
                                             new GradeClassScore(){Grade = 1, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}},
                                             new GradeClassScore(){Grade = 1, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}},
                                             new GradeClassScore(){Grade = 1, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}},
                                             new GradeClassScore(){Grade = 1, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}},
                                             new GradeClassScore(){Grade = 2, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}},
                                             new GradeClassScore(){Grade = 2, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}},
                                             new GradeClassScore(){Grade = 2, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}},
                                             new GradeClassScore(){Grade = 2, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}},
                                             new GradeClassScore(){Grade = 2, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}},
                                             new GradeClassScore(){Grade = 3, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}},
                                             new GradeClassScore(){Grade = 3, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}},
                                             new GradeClassScore(){Grade = 3, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}},
                                             new GradeClassScore(){Grade = 3, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}},
                                             new GradeClassScore(){Grade = 3, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}}
                                         };

 

이제 준비는 마쳤습니다. 위 배열에서 1학년 중에서 점수가 60점 미만인 학급과 과목 점수를 중첩 from 절을 이용해서 뽑아 보겠습니다. 그리고 여기서 한가지 팁을 더 알려 드리자면 where 절에 and, or 를 포함 시킬 수 있습니다. 즉 and => &&, or => || 를 사용하시면 됩니다.

            var classes = from c in arrClass
                            from s in c.Score
                            where s < 60 && c.Grade == 1
                            orderby s
                          select new { c.ClassName, Lowest = s };

전체 소스

    class GradeClassScore
    {
        public int Grade { get; set; }
        public string ClassName { get; set; }
        public int[] Score { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            GradeClassScore[] arrClass = {
                                             new GradeClassScore(){Grade = 1, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}},
                                             new GradeClassScore(){Grade = 1, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}},
                                             new GradeClassScore(){Grade = 1, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}},
                                             new GradeClassScore(){Grade = 1, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}},
                                             new GradeClassScore(){Grade = 1, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}},
                                             new GradeClassScore(){Grade = 2, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}},
                                             new GradeClassScore(){Grade = 2, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}},
                                             new GradeClassScore(){Grade = 2, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}},
                                             new GradeClassScore(){Grade = 2, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}},
                                             new GradeClassScore(){Grade = 2, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}},
                                             new GradeClassScore(){Grade = 3, ClassName = "연두반", Score = new int[]{10, 20, 30, 40, 50}},
                                             new GradeClassScore(){Grade = 3, ClassName = "분홍반", Score = new int[]{65, 75, 85, 95, 100}},
                                             new GradeClassScore(){Grade = 3, ClassName = "파랑반", Score = new int[]{68, 28, 38, 48, 58}},
                                             new GradeClassScore(){Grade = 3, ClassName = "노랑반", Score = new int[]{83, 84, 85, 86, 86}},
                                             new GradeClassScore(){Grade = 3, ClassName = "보라반", Score = new int[]{87, 87, 87, 87, 87}}
                                         };

            var classes = from c in arrClass
                            from s in c.Score
                            where s < 60 && c.Grade == 1
                            orderby s
                          select new { c.ClassName, Lowest = s };

            foreach(var c in classes)
                Console.WriteLine("낙제 : {0} ({1})", c.ClassName, c.Lowest);

            Console.ReadLine();

        }
    }

 

 

posted by 따시쿵
prev 1 2 3 4 5 6 7 8 ··· 38 next