2011-02-10 3 views
40

두 세트의 datarow가 있습니다. 그들은 각각 IEnumerable입니다. 이 두 목록을 하나의 목록에 추가/연결하려고합니다. 나는 이것이 가능하다고 확신한다. for 루프를 수행하고 싶지 않고 두 목록에 Union 메서드와 Join 메서드가 있음을 알았습니다. 어떤 아이디어?두 개의 IEnumerable 시퀀스 추가/연결

+0

동일한 유형의 데이터row 세트가 있습니까? 다른 유형? – Oded

+0

@Obed .... 그들은 같은 타입이다 – MikeTWebb

답변

87

개체의 유형이 동일하다고 가정하면 Union 또는 Concat을 사용할 수 있습니다. SQL UNION 키워드와 마찬가지로 Union 연산을 사용하면 중복이 제거되고 Concat (예 : UNION ALL)과 같이 두 번째 목록이 첫 번째 끝에 추가됩니다. 서로 다른 유형의 경우

IEnumerable<T> first = ...; 
IEnumerable<T> second = ...; 

IEnumerable<T> combined = first.Concat(second); 

또는

IEnumerable<T> combined = first.Union(second); 

는, 당신은 일반적인 무언가로 Select해야합니다. 예를 들어

IEnumerable<TOne> first = ...; 
IEnumerable<TTwo> second = ...; 

IEnumerable<T> combined = first.Select(f => ConvertToT(f)).Concat(
          second.Select(s => ConvertToT(s))); 

어디 ConvertToT(TOne f)ConvertToT(TTwo s)T의 인스턴스로 TOne (및 TTwo 각각)의 인스턴스로 변환하는 동작을 나타낸다.

+0

@ Adam ... fantastic .... 단지 내가 필요로했던 것 – MikeTWebb

+0

@ Adam .... 나는 너무나 일찍 말했다. 나는 연합을 해냈다. 나는 중복 된 기록을 얻고있다. 어떤 종류의 핵심 속성을 초기화하려면 Ineed를 사용합니까? – MikeTWebb

+1

@MikeTWebb :'Union'은 당신이'IEqualityComparer'를 지정할 수있는 오버로드를 가지고 있습니다. –

1

방금 ​​여러 시퀀스를 연결해야하는 비슷한 상황이 발생했습니다.

자연스럽게 Google/StackOverflow에서 기존 솔루션을 검색했지만 열거 형을 평가하지 않은 항목을 찾지 못했습니다 (예 : 배열로 변환 한 다음 Array.Copy() 등을 사용하여 ConcatMultiple이라는 확장명과 정적 유틸리티 메서드를 작성했습니다.

희망 사항은 동일한 작업을 수행해야하는 사용자에게 도움이되기를 바랍니다.

/// <summary> 
/// Concatenates multiple sequences 
/// </summary> 
/// <typeparam name="TSource">The type of the elements of the input sequences.</typeparam> 
/// <param name="first">The first sequence to concatenate.</param> 
/// <param name="source">The other sequences to concatenate.</param> 
/// <returns></returns> 
public static IEnumerable<TSource> ConcatMultiple<TSource>(this IEnumerable<TSource> first, params IEnumerable<TSource>[] source) 
{ 
    if (first == null) 
     throw new ArgumentNullException("first"); 

    if (source.Any(x => (x == null))) 
     throw new ArgumentNullException("source"); 

    return ConcatIterator<TSource>(source); 
} 

private static IEnumerable<TSource> ConcatIterator<TSource>(IEnumerable<TSource> first, params IEnumerable<TSource>[] source) 
{ 
    foreach (var iteratorVariable in first) 
     yield return iteratorVariable; 

    foreach (var enumerable in source) 
    { 
     foreach (var iteratorVariable in enumerable) 
      yield return iteratorVariable; 
    } 
} 

/// <summary> 
/// Concatenates multiple sequences 
/// </summary> 
/// <typeparam name="TSource">The type of the elements of the input sequences.</typeparam>   
/// <param name="source">The sequences to concatenate.</param> 
/// <returns></returns> 
public static IEnumerable<TSource> ConcatMultiple<TSource>(params IEnumerable<TSource>[] source) 
{ 
    if (source.Any(x => (x == null))) 
     throw new ArgumentNullException("source"); 

    return ConcatIterator<TSource>(source); 
} 

private static IEnumerable<TSource> ConcatIterator<TSource>(params IEnumerable<TSource>[] source) 
{ 
    foreach (var enumerable in source) 
    { 
     foreach (var iteratorVariable in enumerable) 
      yield return iteratorVariable; 
    } 
} 
1

Join 방법은 목록이 교차 조건에 따라 참조되는 SQL 조인처럼, 그것은 문자열 연결 또는 목록에 추가되지 않습니다. Union 메서드는 Concat 메서드와 마찬가지로 원하는대로 처리하지만 모두 LAZY 평가이며 매개 변수가 null이 아니도록 요구합니다. ConcatIterator 또는 UnionIterator를 반환하고 if called repeatedly this could cause problems을 반환합니다. 열망하는 평가 결과가 다른 행동으로 나타나면 원하는대로 선택하면 다음과 같은 확장 방법을 사용할 수 있습니다.

public static IEnumerable<T> myEagerConcat<T>(this IEnumerable<T> first, 
                IEnumerable<T> second) 
{ 
    return (first ?? Enumerable.Empty<T>()).Concat(
      (second ?? Enumerable.Empty<T>())).ToList(); 
} 
관련 문제