2012-06-26 1 views
0

두 개의 일반 목록 인 List가 있고 Place.Id 속성을 기반으로 모든 고유 한 Place 개체를 하나의 목록으로 병합하려면이 작업을 효율적으로 수행하는 좋은 방법이 무엇입니까?C#을 사용하면 동일한 유형의 두 가지 일반 목록을 비교/병합하는 효율적인 방법은 무엇입니까?

하나의 목록에는 항상 50 개가 포함되며 다른 목록에는 훨씬 많은 수가 포함될 수 있습니다.

답변

1

당신이 람다 표현식을 사용하여 그냥 자신의 ElementComparer을 정의하는 것을 피하기 위해 원하는 경우, 다음을 시도 할 수 있습니다 :

List<Place> listOne = /* whatever */; 
List<Place> listTwo = /* whatever */; 
List<Place> listMerge = listOne.Concat(
          listTwo.Where(p1 => 
           !listOne.Any(p2 => p1.Id == p2.Id) 
          ) 
         ).ToList(); 

는 본질적으로 이것은 단지 요소가 listOne와 listTwo 사이의 교차점에 있지 않도록 listTwo의 모든 요소들의 집합으로 Enumerable에서 listOne을 연결합니다.

+0

나는이 해결책을 좋아한다. 단점은 무엇인가? 내가 알아야 할게있어? 하나의 목록은 최대 50 개의 개체를 가질 수 있지만 다른 목록에는 수천 개의 개체가있을 수 있습니다! – Chaddeus

+0

글쎄, 이것은 당신의 표준'노조 '입니다. 그것은 당신의 경우에 매우 효율적이어야하며 IEnumerable.Any() 확장은 short-circuits (즉, 한 번 일치하는 데 성공하자마자 true를 반환하고 컬렉션을 반복하여 반복하지 않기 때문에) 좋습니다. 물론, 당신은 더 많은 공상을 가져올 수 있고 당신의 50 객체 목록을 주문할 수 있고 자신의 EqualityComparer를 이진 검색 목록에 쓸 수는 있지만, 내 생각에 이것은 당신에게 좋을 것입니다. 자신의 테스트를 수행하고 효율적인지를 확인하십시오. –

+0

난 그냥 빨리 벤치마킹을 했어, 자신의 IEqualityComparer 인터페이스를 작성하는데 시간을 투자하는 것이 위와 비교할 만하다. http://msdn.microsoft.com/en-us/library/bb358407#snippetGroup –

1

Enumerable.Distinct Method

참고 : 위의 .NET 3.5 &.

+0

먼저 세트를 함께 가입해야합니다. –

+0

참. 그 사실을 완전히 잊었습니다. 그런 다음이 방법은 OP 요구 사항을 충족하지 않습니다. – viclim

2
result = list1.Union(list2, new ElementComparer()); 

IEqualityComparer를 구현하려면 ElementComparer를 만들어야합니다. 예 : 당신이 효율성을 강조하고 싶은 경우 this

1

를 참조, 나는 자신을 병합 당신이 할 수있는 작은 방법을 쓰기 제안 :

List<Place> constantList;//always contains 50 elements. no duplicate elements 
List<Place> targetList; 
List<Place> result; 

Dictionary<int, Place> dict; 
for(var p in constantList) 
    dict.Put(p.Id,p); 

result.AddRange(constantList); 

for(var p in targetList) 
{ 
    if(!dict.Contains(p.Id)) 
     result.Add(p)  
} 
0

속도가 필요한 경우 해싱 메커니즘을 사용하여 비교해야합니다. 내가 한 것은 이미 읽은 ID의 HashSet을 유지 한 다음 ID가 아직 읽지 않은 경우 결과에 요소를 추가하는 것입니다. 병합이 끝나기 전에 소비하기를 원한다면 원하는 수만큼 목록에 대해이 작업을 수행 할 수 있으며 목록 대신 IEnumerable을 반환 할 수 있습니다.

public IEnumerable<Place> Merge(params List<Place>[] lists) 
{ 
    HashSet<int> _ids = new HashSet<int>(); 
    foreach(List<Place> list in lists) 
    { 
     foreach(Place place in list) 
     { 
      if (!_ids.Contains(place.Id)) 
      { 
       _ids.Add(place.Id); 
       yield return place; 
      } 
     } 
    } 
} 

하나의 목록에는 50 개의 요소가 있고 다른 하나의 목록에는 많은 의미가 없다는 사실이 있습니다. 목록이 주문되었음을 안다면 ...

관련 문제