PROGRAMMING WORKSHOP

.Net FrameWork,VB.Net |

LINQ| Aggregating

그룹핑을 하면 그룹핑된 대상의 요약계산된 정보를 얻고 싶어진다
이런 요약작업을 Aggregating,그리고 이때 활용되는 함수들
이것은 엑셀의 부분합이나 피봇테이블에도 있고
SQL언어에서도 있고, 모든 프로그래밍언어에는 기본적으로 갖고 있는 것
이것을 LINQ라는 언어에서도 역시 없어서는 안되는 것이고
Enumerable개체의 다양한 메소드로 제공된다
다시 한번 이야기해서 Enumerable은 .NetFrameWork의 집합체에 포함된
,좀 헷갈리겠지만 IEnumerable Interface를 각 집합체에서
Implementing을 통하여 얻게되는 개체이고,
이것이 LINQ언어에서 실행대상이 되는 집합체가 되는 셈이다
그래서 LINQ를 지원받지 못하는 집합체는 지원받는 집합체타입으로
변환하여 처리하면 된다, 그러니 모든 집합체는 LINQ작업이 가능한 셈
만약 엑셀범위를 옮기고 작업을 한다면 엑셀의 집합체는 LINQ작업대상이
안된다, 엑셀의 범위등을 .NetFrameWork의 적당한 집합체에
옮겨 놓고 작업을 하게 되는 것이다
이것은 좀더 구체적 작업을 할때 당연히 다루게 될 것이니
기초를 하나, 하나 챙기는데 관심을 우선 갖도록 하자

아무튼..
Aggregating은 요약계산을 한다는 것
예를 들어 보는 것이 가장 이해하기 쉬우니..
아래와 같이 하는 것은..

 Dim oQ = (From Q In {"Ab", "DGE", "GEGML", "B", "GREEN"}
                Select Q.Length).Average

 MsgBox(oQ)

Average가 Aggregating (요약계산)하는 일을 하는 메소드..
배열도 하나의 집합체이니까, 그냥 직접 배열을 LINQ내에 넣어도 유효한
집합체로 보는 것이니, 위와 같이 직접넣고..
이때 각 배열요소는 문자열이고 그러니 하나,하나의 배열요소의 문자갯수(Q.Length)로
하여 문자길이를 집합체로 얻어낸 것이고, LINQ결과에 괄호를 앞뒤로 치고
Average메소드를 사용하면 평균 문자갯수가 만들어진다
위의 표현은 아래와 같이 해도 된다

Dim oQ = From Q In {"Ab", "DGE", "GEGML", "B", "GREEN"}
		Select Q.Length

MsgBox("총문자의 갯수는 =" & oQ.Sum & vbNewLine & "총문자갯수의 평균은=" & oQ.Average)

LINQ| Aggregate,Into

이제 LINQ의 키워드 Aggregate를 사용해 보자
어떤숫자배열의 가장 큰값이 얼만지 알고 싶다
위에서 Max메소드를 사용해도 되지만, LINQ의 키워드 Aggregate를 사용해 보자
항상 사용하였던 From대신에 Aggregate를 사용했다
그리고 Select대신에 Into를 사용하여 변수에 Max값을 넣었다

 Dim oQ = Aggregate Q In {34, 23, 45, 545, 1}
                 Into p = Max()
				 
				  MsgBox(oQ)

이것은 요약된 단일값(Aggreating 된값)을 갖여 오라는 표현이다
위에서 하나의 변수에 Max값을 넣은 것은 oQ자체가 하나의 단일값 변수가 되게 되지만
만약 큰값과 작은 값두개를 가져 온다면
변수를 두개를 만들어서 가져온다

 Dim oQ = Aggregate Q In {34, 23, 45, 545, 1}
                Into maxValue = Max(), minValue = Min()

        MsgBox("가장 큰값은=" & oQ.maxValue & "   가장 작은값은=" & oQ.minValue)

배열 {....}에 있는 값들을(In) 요약하여(Aggregate)
하나는 maxValue라는 변수에 Max값을 다른 하나는 minValue라는 변수에 Min값을 넣어서(Into) 가져오라..
From 대신에 Aggreate, Select 대신에 Into를 사용했다

LINQ| Extension Method- Aggregate, User Defined Extension Method..

단어하나 더 챙기자,
Extension Method 이것은 앞에서 이미 사용했었다
개체.ForEach(Sub(x).....) 와 같이
ForEach라고 하였던 것도 Extension Method의 하나였다
Extension Method는 크래스를 만들때 크래스에 메소드를 만들어
넣을수 있는 방법이다
Extension Method를 만드는 방법은 조금있다가 해보도록 하고
이미 만들어져서 제공되는 Extension Method를 사용하도록 하자
LINQ를 좀더 간략하게 표현하도록 더욱 노력하는 셈이다
만약 어느 집합체에 1에서 부터 10까지 들어 있다고 치고 이것을 1*2*3*,,, 와 같이 계속곱한값을 얻고 싶다고 치자

   Dim oQ = Enumerable.Range(1, 10).Aggregate(Function(x, y) x * y)

        MsgBox(oQ)

Enumerable의 Range 메소드로 1에서 부터 10까지 요소로 구성된 Enumerable 집합체가
만들어지고,
즉 아래와 같이 한것을 Enumerable개체의 성질머리를 알면 간단하게 하는것


  Dim oList As Integer() = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
  Dim oQ = oList.Aggregate(Function(x, y) x * y)
  MsgBox(oQ)

아무튼 만들어낸 집합체에 다시 Aggregate메소드(Extension Method)를 사용하고
이 메소드는 Delegate를 매개변수로 받아서 계산하게 한것
아하..앞페이지에서 했던 Delegate를 다시 보아야겠다!!
하는 생각이 드시면 다시 보셔도 되고,그냥 메소드의 매개변수로
함수나 프로시져를 보낼수 있고, 이것을 보내는 방법을
Delegate를 사용한다고 생각하시면 된다

Extension Method를 하나 만들어 보자
String개체는 .NetFrameWork의 개체이다
이 String개체에 마치 .NetFrameWork에서 제공된 메소드 같이 만들어 붙이는 것이다
일반 모듈시트를 하나 삽입하고(적당히 이름을 짓고)
아래와 같이 입력한다


Imports System.Runtime.CompilerServices
Module modExtensionSample


    <Extension()>
    Public Sub SayMe(ByVal sX As String)
        MsgBox("UNO21.COM---VB.NetSample : " & sX)
    End Sub
End Module

System.Runtime.CompilerServices 를 Import시키는 것은
해당 프로젝트를 콤파일 하면서 콤파일러가 작성한 Extension 메소드를
해당개체에 마치 이미있었던 메소드같이 만들어주는 작업을
해주는 것..
물론 이것을 Import시키지 않으면 에러가 날것이고..
이것을 사용하는 윈도우폼에서 아래와 같이 사용하면 된다

    Private Sub Button6_Click(sender As System.Object, e As System.EventArgs) Handles Button6.Click
        Dim oX As String = "Extesion Method 해보기"
        oX.SayMe()
    End Sub

SayMe라는 메소드를 String 개체의 메소드같이 호출하면 되는 것
아래의 쌤플화일에서 실행보시면, 아하..
물론 이것도 편리하게 하는 것이지, 꼭 해야 되는 것은 아니다
그리고 특별한 소루션이 아니고는 제공하는 메소드를 사용하기도
바쁘니 별로 신경쓰지 않아도 된다
하지만, Extension Method가 뭔지를 알아두는 것은 좋으니까..
지루한 키워드들을 별로 재미없게 살펴보았다
키워드를 모두 살펴보진 않았지만
다음 페이지에서 실제적으로 활용을 해보도록하면서
이야기 하지 않은 LINQ의 키워드들을 더 살펴보면서
익숙해지도록 해보자

***[LOG-IN]***