2011-02-10 44 views
40

Tôi có hai bộ dữ liệu. Họ là mỗi IEnumerable. Tôi muốn nối/ghép hai danh sách này vào một danh sách. Tôi chắc chắn điều này là có thể thực hiện được. Tôi không muốn làm một vòng lặp for và nhận thấy rằng có một phương thức Union và một phương thức Join trên hai Lists. Bất kỳ ý tưởng?Thêm/ghép nối hai chuỗi IEnumerable

+0

Là tập các datarows cùng loại? Các loại khác nhau? – Oded

+0

@Obed .... chúng thuộc cùng một loại – MikeTWebb

Trả lời

87

Giả sử đối tượng của bạn cùng loại, bạn có thể sử dụng Union hoặc Concat. Lưu ý rằng, giống như từ khóa UNION của SQL, hoạt động Union sẽ đảm bảo rằng các bản sao bị loại bỏ, trong khi Concat (như UNION ALL) sẽ chỉ thêm danh sách thứ hai vào cuối danh sách đầu tiên.

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

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

hoặc

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

Nếu họ là các loại khác nhau, sau đó bạn sẽ phải Select chúng thành nội dung chung. Ví dụ:

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

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

đâu ConvertToT(TOne f)ConvertToT(TTwo s) đại diện cho một hoạt động nào đó chuyển đổi một thể hiện của TOne (và TTwo, tương ứng) vào một thể hiện của T.

+0

@Adam ... tuyệt vời .... chỉ là những gì tôi cần – MikeTWebb

+0

@Adam .... Tôi đã nói quá sớm. Tôi đã thực hiện Liên minh Tôi đang nhận được hồ sơ trùng lặp. Làm Ineed để khởi tạo một thuộc tính quan trọng của một số loại? – MikeTWebb

+1

@MikeTWebb: 'Union' có quá tải cho phép bạn chỉ định một' IEqualityComparer'. –

1

Tôi vừa gặp phải tình huống tương tự mà tôi cần ghép nối nhiều chuỗi.

Tìm kiếm các giải pháp hiện có trên Google/StackOverflow một cách tự nhiên, tuy nhiên không tìm thấy bất kỳ thứ gì không đánh giá số đếm được, ví dụ: chuyển đổi thành mảng sau đó sử dụng Array.Copy() v.v., vì vậy tôi đã viết một phần mở rộng và phương thức utiltiy tĩnh được gọi là ConcatMultiple.

Hy vọng điều này sẽ giúp mọi người cần làm như vậy.

/// <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

Phương pháp Join giống như một SQL tham gia, trong đó danh sách được qua tham chiếu dựa trên một điều kiện, nó không phải là một nối chuỗi hoặc Thêm vào một danh sách. Phương thức Union thực hiện những gì bạn muốn, cũng như phương thức Concat, nhưng cả hai đều là các đánh giá LAZY và có yêu cầu tham số là không null. Họ trả về một ConcatIterator hoặc một UnionIterator, và if called repeatedly this could cause problems. Kết quả đánh giá bằng cách đánh giá theo hành vi khác nhau, nếu đó là những gì bạn muốn, thì có thể sử dụng một phương pháp mở rộng như dưới đây.

public static IEnumerable<T> myEagerConcat<T>(this IEnumerable<T> first, 
                IEnumerable<T> second) 
{ 
    return (first ?? Enumerable.Empty<T>()).Concat(
      (second ?? Enumerable.Empty<T>())).ToList(); 
} 
Các vấn đề liên quan