2012-04-16 2 views
7

어떤 조건과 일치하는 항목을 목록에서 제거한 다음 해당 항목을 가져 오는 가장 쉬운 방법은 어느 것입니까?LINQ : RemoveAll 및 get 요소 제거

var subList = list.Where(x => x.Condition); 
list.RemoveAll(x => x.Condition); 

또는

var subList = list.Where(x => x.Condition); 
list.RemoveAll(x => subList.Contains(x)); 

이 가장 좋은 방법이 하나의인가 :

은 내가 최고의 하나입니다 모르는 몇 가지 방법으로 생각할 수있다? 그렇다면 어느 것입니까? 그렇지 않다면 어떻게해야합니까?

답변

4

내가 먼저 목록을 구체화해야한다, 또는 당신은 당신이 다음 줄에 선택하려는 매우 항목을 잃게됩니다 노트로, 가독성을 위해 첫 번째 옵션과 함께 갈 것입니다 :

var sublist = list.Where(x => x.Condition).ToArray(); 
list.RemoveAll(x => x.Condition); 

두 번째 예제는 아무런 이유없이 O (n^2)이고 마지막은 완벽하지만 괜찮습니다.

편집 : 마지막 예제를 다시 읽었으니, 지금 쓰여진대로 다른 모든 항목이 제거됩니다. 제거한 후 i+1 번째 요소가 i 번째 요소가되고, i이 증가하면 건너 뜁니다. 따라서 조건 검사가 누락되었습니다. 제거 줄은 실제로 list.RemoveAt(i--);이어야합니다.

+0

을 원본 인스턴스를 수정해야하는 경우) – Blindy

+0

SubList에서 두 번째 명령을 사용하여 항목을 삭제 했습니까? : O – Diego

+0

어쨌든 당신은'sublist'에서 절대로 제거 할 수 없으며 올바르게 읽으 려하지 않습니다. – Blindy

2

저는 기능 프로그래밍 접근법 (새로운 것을 만들거나 기존의 것을 수정하지 마십시오)을 사용하고 싶습니다. ToLookup의 장점 중 하나는 항목의 양방향 분할 이상을 처리 할 수 ​​있다는 것입니다.

ILookup<bool, Customer> lookup = list.ToLookup(x => x.Condition); 
List<Customer> sublist = lookup[true].ToList(); 
list = lookup[false].ToList(); 

아니면 실제로 O입니다 (N^3),하지만 난 물질화의 부족은 당신의 마음을 미끄러 있으리라 믿고있어 ...

list.Clear(); 
list.AddRange(lookup[false]); 
+0

필자는 그것이 매우 복잡하다고 생각한다. 이점이 있습니까? – Diego

+0

조건은 항목 당 정확히 한 번 평가됩니다.목록 인스턴스가 수정되지 않았으므로 목록 인스턴스가 스레드간에 공유되면 큰 이점이 될 수 있습니다. –