2016-09-20 3 views
4

이 문제가 하나 있습니다. 문자열이 있습니다C# 문자열 배열에서 가장 일반적인 문자열 찾기

string [5] names = { "John", "Sam", "Harry", "Sam", "John" } 

배열에서 가장 일반적인 요소를 찾아야합니다. 나는 사용하여 시도 :

string MostCommon = names.GroupBy(v => v) 
    .OrderByDescending(g => g.Count()) 
    .First() 
    .Key; 

불행하게도 그것은 단지 하나 개의 요소, f.e., MostCommon = John을 발견,이 경우 나는뿐만 아니라 John하지만 Sam도 필요합니다. 내가 어떻게 할 수 있니? 어쩌면 LINQ가 필요하지 않을까요?

+1

'좁은 방()가'문제입니다 - 다음과 같이

string MostCommon = names.GroupBy(v => v) .OrderByDescending(g => g.Count()) .First(); int count = names.Where(x => x == MostCommon).Count(); var mostCommonList = names.GroupBy(v => v) .Where(g => g.Count() == count); 
dckuehn

+0

[List에서 최대 반복되는 항목 반환] 가능한 복제본 (http://stackoverflow.com/questions/15184598/return-max-repeated-item-in-list) – neverendingqs

+3

아니요, 복제본은 OP가 원하지 않는 것을 만듭니다. 첫 번째 최대 값을 선택하십시오. 그것은 하나 이상의 멤버가 최대 카운트를 가질 수있는 OP의 경우를 처리하지 않습니다. – HimBromBeere

답변

4

을 수행 할 수있다. `.First()`를 없애면 둘 이상의 결과를 얻을 수 있지만 그 단일 LINQ 문으로 특정 개수를 알 수는 없습니다.
9

First은 분명히 시퀀스의 첫 번째 요소 만 선택합니다. 그러나 동일한 수의 모든 그룹이 필요합니다. 따라서 그룹당 이름과 번호를 선택하고 다음에을 주문하십시오. 마지막으로 매우 첫 번째 그룹과 동일한 수의 그룹을 모두 선택하십시오.

var groups = names.GroupBy(x => x) 
    .Select(x => new { x.Key, Count = x.Count() }) 
    .OrderByDescending(x => x.Count); 
int max = groups.First().Count; 
var mostCommons = groups.Where(x => x.Count == max); 

편집 : 당신은 또한 groups -list의 마지막 요소에 대한 불필요한 비교를 피하고 첫 번째 그룹은 처음보다 적은 요소를 가진 발견되었을 때 즉시 정지되는 마지막 성명에서 TakeWhile 대신 Where을 사용할 수 있습니다 하나 :

var mostCommons = groups.TakeWhile(x => x.Count == groups.First().Count); 
+0

이것은'group' 쿼리 (그룹핑과 순서 포함)를 많은 시간 실행하는 매우 비효율적 인 방법입니다. 최소한'groups.First(). Count '를 마지막 쿼리 외부의 변수에 넣으면'groups' 쿼리가 "only"를 두 번 실행하게됩니다. 여전히 Amit Hasan 접근법보다 더 나을 것이고 (가능한 LINQ가 아닌 가능한 솔루션을 세지 않음), 적어도 그렇게 나쁘지는 않습니다. –

+0

'TakeWhile'의'Where'에 대한 장점에 대한 좋은 지적입니다. 장래의 독자를 위해서'TakeWhile'을 사용하여 스 니펫을 추가하는 것을 고려해야하며,'TakeWhile'가 더 나은 선택이기 때문에'Where' 코드를 완전히 삭제할 수도 있습니다. – BACON

+0

@BACON 완료. – HimBromBeere

4

발견 한 가장 일반적인 이름의 개수를 기반으로 유사한 LINQ와 첫 번째 LINQ를 결합하십시오.

var nameGroup = names.GroupBy(x => x); 
var maxCount = nameGroup.Max(g => g.Count()); 
var mostCommons = nameGroup.Where(x => x.Count() == maxCount).Select(x => x.Key).ToArray(); 
+0

이것은 마지막 줄에 존재하지 않는'.Key' 속성 ('mostCommonList'를 할당 할 때'='추가)을 더하여 컴파일되지 않습니다. "가장 일반적인 이름"이 하나만 있다고 가정 할 수 없으므로 결과는'string'이 아닌'IEnumerable '이어야합니다.그러므로,'.Key'는 제거되어야합니다 (또는 유용성이 떨어지면'.Select (v => v)'로 대체해야합니다). – BACON

+0

@BACON 너무 많은 나쁜 사본/파스타, 나를 불러 주셔서 고마워. 나는'='을 고쳤고'.Key' 두 문을 모두 제거했습니다. 나는 대답은'.Select()'가 없으면 괜찮을 것이라고 생각한다.'.Where'가 열거 형을 반환 할 것이기 때문에. – dckuehn

관련 문제