두 개의 일반 목록 인 List가 있고 Place.Id 속성을 기반으로 모든 고유 한 Place 개체를 하나의 목록으로 병합하려면이 작업을 효율적으로 수행하는 좋은 방법이 무엇입니까?C#을 사용하면 동일한 유형의 두 가지 일반 목록을 비교/병합하는 효율적인 방법은 무엇입니까?
하나의 목록에는 항상 50 개가 포함되며 다른 목록에는 훨씬 많은 수가 포함될 수 있습니다.
두 개의 일반 목록 인 List가 있고 Place.Id 속성을 기반으로 모든 고유 한 Place 개체를 하나의 목록으로 병합하려면이 작업을 효율적으로 수행하는 좋은 방법이 무엇입니까?C#을 사용하면 동일한 유형의 두 가지 일반 목록을 비교/병합하는 효율적인 방법은 무엇입니까?
하나의 목록에는 항상 50 개가 포함되며 다른 목록에는 훨씬 많은 수가 포함될 수 있습니다.
당신이 람다 표현식을 사용하여 그냥 자신의 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을 연결합니다.
참고 : 위의 .NET 3.5 &.
먼저 세트를 함께 가입해야합니다. –
참. 그 사실을 완전히 잊었습니다. 그런 다음이 방법은 OP 요구 사항을 충족하지 않습니다. – viclim
result = list1.Union(list2, new ElementComparer());
IEqualityComparer를 구현하려면 ElementComparer를 만들어야합니다. 예 : 당신이 효율성을 강조하고 싶은 경우 this
를 참조, 나는 자신을 병합 당신이 할 수있는 작은 방법을 쓰기 제안 :
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)
}
속도가 필요한 경우 해싱 메커니즘을 사용하여 비교해야합니다. 내가 한 것은 이미 읽은 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 개의 요소가 있고 다른 하나의 목록에는 많은 의미가 없다는 사실이 있습니다. 목록이 주문되었음을 안다면 ...
나는이 해결책을 좋아한다. 단점은 무엇인가? 내가 알아야 할게있어? 하나의 목록은 최대 50 개의 개체를 가질 수 있지만 다른 목록에는 수천 개의 개체가있을 수 있습니다! – Chaddeus
글쎄, 이것은 당신의 표준'노조 '입니다. 그것은 당신의 경우에 매우 효율적이어야하며 IEnumerable.Any() 확장은 short-circuits (즉, 한 번 일치하는 데 성공하자마자 true를 반환하고 컬렉션을 반복하여 반복하지 않기 때문에) 좋습니다. 물론, 당신은 더 많은 공상을 가져올 수 있고 당신의 50 객체 목록을 주문할 수 있고 자신의 EqualityComparer를 이진 검색 목록에 쓸 수는 있지만, 내 생각에 이것은 당신에게 좋을 것입니다. 자신의 테스트를 수행하고 효율적인지를 확인하십시오. –
난 그냥 빨리 벤치마킹을 했어, 자신의 IEqualityComparer 인터페이스를 작성하는데 시간을 투자하는 것이 위와 비교할 만하다. http://msdn.microsoft.com/en-us/library/bb358407#snippetGroup –