2012-01-13 2 views
1

을 나는이 목록이 있습니다목록에 (이름을 기준으로) 마지막 요소를 가져옵니다 - LINQ C#을

애니 - P
월 - ""
애니 - P
월 - P

을 P
월 - - P


애니 : 그리고는 이름을 기준으로 마지막 요소를 얻으려면

이 코드를 가지고 있지만 오류가 발생했습니다 : The type arguments for method 'System.Linq.Enumerable.SelectMany<TSource,TResult>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,System.Collections.Generic.IEnumerable<TResult>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly. 또는 목록의 맨 마지막 요소 (5 월 - P) 만 가져옵니다. 덤프()는 LINQPad 확장은 다음과 같습니다

class Passenger 
{ 
    public string Name { get; set; } 
    public int PassengerID { get; set; } 
    public List<TravelDoc> TravelDocs { get; set; } 
} 

class TravelDoc 
{ 
    public string DocType { get; set; } 
    public int? DocNumber { get; set; } 
} 

List<Passenger> modList = new List<Passenger>() 
    { 

     new Passenger() { Name = "Annie", PassengerID = 0, 
          TravelDocs = new List<TravelDoc>() 
          { 
          new TravelDoc() { DocNumber = 100, DocType = "P" } 
          } 
         }, 
     new Passenger() { Name = "May", PassengerID = 1, 
          TravelDocs = new List<TravelDoc>() 
          { 
          new TravelDoc() { DocNumber = null, DocType = "" } 
          } 
         },  
     new Passenger() { Name = "Annie", PassengerID = 0, 
          TravelDocs = new List<TravelDoc>() 
          { 
          new TravelDoc() { DocNumber = 100, DocType = "P" } 
          } 
         }, 
     new Passenger() { Name = "May", PassengerID = 1, 
          TravelDocs = new List<TravelDoc>() 
          { 
          new TravelDoc() { DocNumber = 200, DocType = "P" } 
          } 
         } 
    };  

코드

var passengersMod = modList.SelectMany(pax => pax.TravelDocs   
        .Select(doc => new { Passenger = pax, TravelDoc = doc }) 
        .Last()) 
        .Dump(); 

코드 (잘못된 결과)

var passengersMod = modList.SelectMany(pax => pax.TravelDocs   
        .Select(doc => new { Passenger = pax, TravelDoc = doc }) 
        ).Last() 
        .Dump(); 

주 (오류가 발생합니다). : D

LINQ를 사용하여 원하는 결과를 얻으려면 어떻게해야합니까?

미리 감사드립니다.

편집 :

좋아, 그것은 대부분의 사람들이 "이름을 기반으로"조건과 혼동됩니다 것으로 보인다. 죄송 합니다만 불행히도 기준을 설명하는 더 좋은 단어는 생각할 수 없습니다 (미안). 그러나 Jon Hanna는 내가 의미하는 것을 얻었다, 감사합니다! 또한 제안 된 제목에서 "익명 형식"을 제거했습니다. 다시 한 번 감사드립니다! : D

또 다른 편집 :

나는 약간의 차이가 이와 유사한 다른 상황이있다. 예, 목록은 일부 기준 (이 예에서는 이름)에 따라 그룹화되었지만 각 그룹의 마지막 항목을 필요로하지 않고 필요한 것은 각 그룹의 n 번째 항목입니다.

나는 각 그룹에서 n 번째를 얻을 수있었습니다 :이 질문을

modList.GroupBy(p => p.Name).Select(g => g.ToList()[index]) 

년 후, 존의 대답은 여전히 ​​저를 도왔다. 나는 그의 대답을 두 번 upvote 할 수 있었으면 좋겠어! 이것이 다른 사람을 도울 수 있기를 바랍니다. : D

+0

"이름을 기준으로"어떤 주문을 하시는지 정확하게 알 수 있습니까? – doogle

+0

LOL. 나는 그것이 내가이 시간대에서 거의 취침 시각 인 것을 알았던와 그것이 내가 대부분의 질문에 "TL, DR"에 갔다라고하는 사실을 실제로 얻었던 것이라고 생각한다! :) –

+0

하하. 때로는 특정 문제를 너무 깊이 이해하려고 노력하면 표면 요구 사항을 간과 할 수 있습니다. Lolz. 최고 감사합니다! 들어오는 두통에서 나를 구해 줬어! : P –

답변

4

왜 익명의 유형과 SelectMany을 무시하지 그냥 수행

modList.GroupBy(p => p.Name).Select(g => g.Last()) 

이 있어요 노히 당신의 제목에 따라 익명의 타입을 사용하는 것이지만, 그것은 질문의 시작 부분에서 언급 한 종류의 결과를 낳습니다.

1

우선 SelectMany는 여러 세트를 단일 세트로 집계하는 데 사용됩니다. IEnumerable을IEnumerable> >을 단일 IEnumerable <int>에 변환하는 것을 고려하십시오. 따라서 Last 메서드는 IEnumerable 개체를 나타내지 않는 단일 요소를 반환하므로 사용법을 유추 할 수 없습니다.

// This will return the last 2 elements in your collection. 
modList.Skip(modList.Count() - 2); 
+0

사실 나는 처음에는 그것을 고려했지만 Reverse는 콜렉션의 순서를 뒤집을 때의 오버 헤드를가집니다. 건너 뛰기 만하면 요소를 지나치게 탐색 할 수 있습니다. 그래서 내가했던 코드로 갔다. 그래도 완벽을 위해 주셔서 감사합니다 :) – doogle

+0

당신이 내 의견을 읽지 않기를 바랬는데, 내 의견이 질문과 관련이 없다고 생각하고 삭제했습니다. BTW, 오버 헤드가 그다지 크지 않다고 생각합니다. – 000

+1

오버 헤드는 결과 집합에 더 많은 요소가 포함되어있는 상황에서 문제가 될 수 있습니다. 집합의 개수가 미리 계산 된 값이 아닌 경우 (즉, 열거자를 사용하여 결과를 산출하는 Enumerable 객체) 마지막 몇 요소를 가져온 집합을 반대로 전환하는 방법은 분명 더 빠릅니다. 나는 그것이 질문에 대답하지 않는다는 것을 안다. 그러나이 정보는 아는 것이 아니다. – doogle

1

잘 모르겠어요 : 지금 나는 당신을 아주 "이름을 기반으로 지난 요소"에 의해 의미하지만 당신은 컬렉션의 마지막 N 요소를 얻으려면, 당신이 뭔가를 할 수 있는지 이해가 안 돼요 난 당신이 항목을 주문하는 방법을 이해,하지만 난 당신이 할하려는 것은이 생각 :

var passengersMod = modList.SelectMany(
    d => d.TravelDocs, (p, d) => new { Passenger = p, TravelDoc = d }) 
    .Last() 
    .Dump(); 
+0

이것이 내가 찾은 것입니다. 감사합니다! 괜찮으 시다면 여기서 한 일을 설명해 주시겠습니까? 나는 LINQ 투영 및 집계에서 새로운 것을 알게되었습니다. 왜 d => d.TravelDocs를 만들어야합니까? 다시 한번 감사드립니다. –

+0

음, 두 번째 검사시 ... 5 월 - P 인 마지막 요소 만 반환합니다. 내가 필요한 것은 Annie-P 및 May-P입니다. 귀하의 답변에 감사드립니다. : D –

+0

당신은 아마 더 나은 정보를 찾을 수 있지만 짧은 대답은 [SelectMany] (http://msdn.microsoft.com/en-us/library/bb534631.aspx)는 각 여행자 문서의 목록을 평평하게합니다. 첫 번째 매개 변수) 다음 결과 선택기 (두 번째 매개 변수)를 적용하여 최종 결과를 얻습니다. – Lester

관련 문제