사전 객체로 LINQ 그룹화


161

에서 LINQ를 사용하여를 만들려고 Dictionary<string, List<CustomObject>>합니다 List<CustomObject>. "var"을 사용하여이 작업을 수행 할 수 있지만 익명 형식을 사용하고 싶지 않습니다. 여기 내가 가진 것입니다

var x = (from CustomObject o in ListOfCustomObjects
      group o by o.PropertyName into t
      select t.ToList());

또한 Cast<>()일단 LINQ 라이브러리에서 사용하려고 시도했지만 x유효하지 않은 캐스트의 결과로 컴파일 문제가 발생합니다.


var x = (ListOfCustomObjects 그룹 o의 CustomObject o에서 o.PropertyName으로 t를 선택하여 t를 선택)를 시도하면 어떻게됩니까? ToList ();
esastincy

44
이를 위해 설계된 ToLookup을 사용하는 대신이 작업을 수행해야하는 이유가 있습니까?
Jon Skeet 2016 년

1
Jon,이 상황에서 ToLookup의 작동 방식에 대한 예를 게시 해 주시겠습니까? 나는 그 LINQ 방법에 익숙하지 않다.
Atari2600

8
@JonSkeet 당신은 최고입니다! (모든 사람들은 이미 알고 있었지만 여전히 그렇습니다.) ToLookup 사용을 계획하지 않은 이유는 지금까지 들어 본 적이없는 원인이었습니다. 이제 알아요!
neminem

1
완전성을 위해 var사용하는 것은 "익명"유형을 사용하지 않고 "암시 적"유형을 사용합니다. 익명 형식은 생성자를 처리하기 위해 컴파일러에서 만든 새로운 클래스입니다 new { thing = "stuff" };. 암시 적 유형은 기존 클래스이며 var변수가 즉시 지정 될 때이를 참조하는 편리한 방법 일뿐입니다. 변수 유형은 지정된 오브젝트의 유형에서 유추 할 수 있습니다. 익명 형식을 참조하는 변수를 암시 적으로 입력 할 수도 있습니다.var a = new { thing = "stuff" };
Michael Blackburn

답변:


351
Dictionary<string, List<CustomObject>> myDictionary = ListOfCustomObjects
    .GroupBy(o => o.PropertyName)
    .ToDictionary(g => g.Key, g => g.ToList());

6
목록 값으로 'CustomObject'의 속성이 필요하지 않은 경우 (이 답변에 표시되지 않음) ToLookup ()을 추천하는 질문에 대한 그의 친절도 Jon Skeet의 의견을 확인하는 것이 좋습니다.
Shaun

3
변경 불가능한 결과가 필요한 경우이를 수행하는 방법입니다. ToLookup은 변경할 수 없습니다.
Amit

1
내 2 센트 (단지 한 시간 동안 어려움을 겪었 기 때문에 :)) : 속성별로 그룹화 할 때 속성 값이 있는지 확인하십시오! 그렇지 않으면 Todict-method가 키 생성에 실패합니다 (최소한 문자열 특성의 경우 ...) :
dba

.GroupBy(o => o.PropertyName).ToDictionary(g => g.Key, g => g.ToList())이것은 Linq 라이브러리 확장의 일부일 수 있습니다. 그래서 우리는 상관이.ToDictionary(o=>o.PropertyName)
Jaider

3
단지 대체 : @Jaider, 이미 이러한 기능이 ToDictionary함께가 ToLookup.
Robert Synoradzki

19

@Michael Blackburn에 대해서는 언급 할 수 없지만 GroupBy가 필요하지 않기 때문에 downvote를 얻은 것 같습니다.

다음과 같이 사용하십시오.

var lookupOfCustomObjects = listOfCustomObjects.ToLookup(o=>o.PropertyName);
var listWithAllCustomObjectsWithPropertyName = lookupOfCustomObjects[propertyName]

또한 GroupBy (). ToDictionary ()를 사용할 때보 다 성능이 우수하다는 것을 알았습니다.


나는 가장 좋은 방법으로 질문에 대답하지 않고 음역을 수행하고있었습니다.
Michael Blackburn

1

@ atari2600의 경우 람다 구문에서 ToLookup을 사용하는 방법은 다음과 같습니다.

var x = listOfCustomObjects
    .GroupBy(o => o.PropertyName)
    .ToLookup(customObject => customObject);

기본적으로 IGrouping을 가져와 PropertyName 값을 키로 사용하여 목록 사전으로 구체화합니다.


왜 공감해야합니까? 이것이 정확하지 않은 질문입니까?
Michael Blackburn

1
@RuudvK는 자신 이 놓친 경우 GroupBy가 불필요하기 때문에 다운 보트가 의심된다고 대답 했습니다. ToLookup작업을 완료하는 과부하가 있습니다.
Jeff B

태그를 지정해 주셔서 감사합니다. 이해하기 쉽게 그룹화는 구문 상 불필요합니다. 쿼리 구문에서 메소드 구문으로 더 명확하게 전환하기 위해 그룹화하는 것만 남았습니다.
Michael Blackburn

GroupBy (단 하나의 매개 변수를 가진 과부하)는 IEnumerable <IGrouping <TKey, TSource >>를 후속 ToLookup으로 반환 한 다음 IDictionary <TKey, IList <TSource >>와 비슷하지 않은 매우 복잡한 유형으로 변환합니다. 올바른 유형을 반환합니다.
xtofs

-1

다음은 나를 위해 일했습니다.

var temp = ctx.Set<DbTable>()
  .GroupBy(g => new { g.id })
  .ToDictionary(d => d.Key.id);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.