2011-02-10 36 views
40

我有兩組數據行。它們每個都是IEnumerable。我想將這兩個列表追加/連接成一個列表。我相信這是可行的。我不想做一個for循環,並且注意到兩個列表中有一個Union方法和一個Join方法。有任何想法嗎?附加/連接兩個IEnumerable序列

+0

是相同類型的數據行集?不同種類? – Oded 2011-02-10 19:55:00

+0

@Obed ....他們屬於同一類型 – MikeTWebb 2013-07-16 22:02:41

回答

87

假設您的對象類型相同,則可以使用UnionConcat。請注意,與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)表示的TOne(和TTwo,分別地)的實例以某種方式轉換成的T一個實例的操作。

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評估,並且要求參數爲非空。他們返回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(); 
}