그룹 별 및 개수가 포함 된 LINQ


221

이것은 매우 간단하지만 손실이 있습니다.이 유형의 데이터 세트를 감안할 때 :

UserInfo(name, metric, day, other_metric)

이 샘플 데이터 세트 :

joe  1 01/01/2011 5
jane 0 01/02/2011 9
john 2 01/03/2011 0
jim  3 01/04/2011 1
jean 1 01/05/2011 3
jill 2 01/06/2011 5
jeb  0 01/07/2011 3
jenn 0 01/08/2011 7

카운트가 발생하는 총 횟수와 함께 (0,1,2,3 ..) 순서로 메트릭을 나열하는 테이블을 검색하고 싶습니다. 따라서이 세트에서 다음과 같이 끝납니다.

0 3    
1 2    
2 2    
3 1

LINQ 구문을 사용하고 있지만 그룹을 배치하고 계산할 위치에 붙어 있습니다 .... 어떤 도움?

POST 편집 : 게시 된 답변이 항상 다른 수의 레코드 하나를 반환했기 때문에 게시 된 답변을 얻을 수 없었습니다. 그러나 나는 작동하는 LINQ to SQL 예제를 만들 수있었습니다.

        var pl = from r in info
                 orderby r.metric    
                 group r by r.metric into grp
                 select new { key = grp.Key, cnt = grp.Count()};

이 결과는 나에게 '메트릭'과 그와 관련된 사용자 수를 가진 정렬 된 레코드 세트를 주었다. 나는 일반적으로 LINQ를 처음 접했고 훈련되지 않은 눈 에이 접근법은 순수한 LINQ 접근법과 매우 유사하지만 다른 대답을주었습니다.


예,하지만 지미의 설명이 더 도움이되었습니다. 그러나 나는 그의 모범을 발휘할 수 없었지만 새로운 방향으로 이끌었습니다.
Gio

@Jimmy는 표준 LINQ 쿼리 구문 대신 LINQ 식에 기능 구문을 사용했으며 지연된 실행 형식이 아니라 해당 함수의 즉각적인 실행을 보여 주기로 결정했습니다. 혼란스러운 새로운 사람. 그가 왜 그랬는지 모르겠다.
Richard Robertson

답변:


394

를 호출 GroupBy하면 일련의 그룹 이 생성됩니다. IEnumerable<Grouping>여기서 각 그룹 자체는 Key그룹을 만드는 데 사용 된 IEnumerable<T>항목을 표시하며 원래 데이터 세트에있는 항목 중 하나 입니다. Count()소계를 얻으려면 해당 그룹화 를 호출 하면됩니다.

foreach(var line in data.GroupBy(info => info.metric)
                        .Select(group => new { 
                             Metric = group.Key, 
                             Count = group.Count() 
                        })
                        .OrderBy(x => x.Metric)
{
     Console.WriteLine("{0} {1}", line.Metric, line.Count);
}


이것은 매우 빠른 답변이지만 첫 번째 줄, 특히 "data.groupby (info => info.metric)"에 약간의 문제가 있습니다.

나는 당신이 이미 class보이는 것의 목록 ​​/ 배열을 가지고 있다고 가정합니다.

class UserInfo {
    string name;
    int metric;
    ..etc..
} 
...
List<UserInfo> data = ..... ;

그렇게하면 data.GroupBy(x => x.metric)"에 x의해 정의 된 IEnumerable의 각 요소 에 대해 data의 값을 계산 .metric한 다음 동일한 메트릭을 가진 모든 요소를 ​​a 로 그룹화하고 모든 결과 그룹 중 하나 Grouping를 반환합니다 IEnumerable.

    <DATA>           | Grouping Key (x=>x.metric) |
joe  1 01/01/2011 5  | 1
jane 0 01/02/2011 9  | 0
john 2 01/03/2011 0  | 2
jim  3 01/04/2011 1  | 3
jean 1 01/05/2011 3  | 1
jill 2 01/06/2011 5  | 2
jeb  0 01/07/2011 3  | 0
jenn 0 01/08/2011 7  | 0

그룹별로 다음과 같은 결과가 나타납니다.

(Group 1): [joe  1 01/01/2011 5, jean 1 01/05/2011 3]
(Group 0): [jane 0 01/02/2011 9, jeb  0 01/07/2011 3, jenn 0 01/08/2011 7]
(Group 2): [john 2 01/03/2011 0, jill 2 01/06/2011 5]
(Group 3): [jim  3 01/04/2011 1]

이것은 매우 빠른 답변이지만 첫 번째 줄, 특히 "data.groupby (info => info.metric)"에 약간의 문제가 있습니다. 일반적으로 '데이터'는 현재 데이터 세트이지만 'info.metric'은 무엇을 다시 사용합니까? 클래스 정의?
Gio

"info.metric"은 질문에서 언급 한 UserInfo 클래스의 메트릭 속성 / 필드입니다.
lee-m

1
고맙다는 것을 알았지 만 실제로 이것은 하나의 값, 즉 다른 메트릭 수의 총 수를 나타내는 것으로 보입니다. 이 예에서는 "계수 4"를 얻습니다.이 숫자는 몇 개의 다른 계수가 있는지 알려줍니다.
Gio

1
와. 당신은 그룹화를 완전히 설명했다!! 그것만으로도 가치가 있었다 .... 나는 아직도 "메트릭 4"결과를 얻지 만 감사합니다!
Gio

4
이 답변의 시작은 "GroupBy를 호출 한 후 일련의 그룹 IEnumerable <Grouping>을 얻습니다. 여기서 각 Grouping 자체는 그룹을 만드는 데 사용 된 Key를 노출하며 원래 데이터에있는 항목의 IEnumerable <T>입니다. set "은 LINQ Group에 대한 가장 명확한 설명입니다.
dumbledad

48

가정 userInfoListList<UserInfo>:

        var groups = userInfoList
            .GroupBy(n => n.metric)
            .Select(n => new
            {
                MetricName = n.Key,
                MetricCount = n.Count()
            }
            )
            .OrderBy(n => n.MetricName);

에 대한 람다 함수는 GroupBy(), n => n.metric이 필드를 얻을 것을 의미합니다 metric모든에서 UserInfo발생하는 객체입니다. 의 유형은 n컨텍스트에 따라 다릅니다 . UserInfo목록에는 UserInfo객체 가 포함되어 있기 때문에 첫 번째 유형은 유형 입니다. 두 번째 항목 n의 유형은이며 Grouping, 이제는 Grouping객체 목록이기 때문 입니다.

GroupingS는 확장 등의 방법이 .Count(), .Key()당신이 기대하는 다른 거의 아무것도. 를 확인 .Lenght하는 것처럼 그룹을 string확인할 수 있습니다 .Count().


23
userInfos.GroupBy(userInfo => userInfo.metric)
        .OrderBy(group => group.Key)
        .Select(group => Tuple.Create(group.Key, group.Count()));

1
group.keySelect (...)의 small typo-> 는 다음과 같아야합니다.group.Key
Jan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.