2010-08-04 36 views
9

Tôi cần phải thêm một giá trị vào một IEnumerable (trong trường hợp này là IEnumerable<string[]>). Để làm điều đó, Tôi đang tạo List<T> chỉ để quấn giá trị đầu tiên để tôi có thể gọi Concat:Cách dễ dàng để nối thêm hoặc thêm một giá trị đơn lẻ vào một số điện thoại IE2umerlà gì?

// get headers and data together 
IEnumerable<string[]> headers = new List<string[]> { 
    GetHeaders() 
}; 
var all = headers.Concat(GetData()); 

Yuck. Có cách nào tốt hơn? Và làm thế nào bạn sẽ xử lý các trường hợp ngược lại của phụ thêm một giá trị?

Trả lời

23

tôi đã viết các phương pháp mở rộng thông thường để làm điều này:

public static IEnumerable<T> Append<T>(this IEnumerable<T> source, T item) 
{ 
    foreach (T i in source) 
     yield return i; 

    yield return item; 
} 

public static IEnumerable<T> Prepend<T>(this IEnumerable<T> source, T item) 
{ 
    yield return item; 

    foreach (T i in source) 
     yield return i; 
} 

Trong kịch bản của bạn, bạn sẽ viết:

var all = GetData().Prepend(GetHeaders()); 

Như chilltemp nhận xét, điều này không làm thay đổi bộ sưu tập gốc. Trong thời trang Linq thực sự, nó tạo ra một IEnumerable<T> mới.

Lưu ý: Kiểm tra đối số rỗng mong muốn được đề xuất cho source, nhưng không được hiển thị cho ngắn gọn.

+0

Rất tuyệt! Tôi có một số trong thư viện của tôi giống như những thư viện đó. – kbrimington

+3

Thanh lịch. Cần lưu ý rằng điều này sẽ trả về một IEnumerable mới bằng cách liệt kê bộ sưu tập hiện có. Nó không thực sự thêm/thêm vào bộ sưu tập gốc. – chilltemp

7

Sử dụng phương thức mở rộng Enumerable.Concat. Để thêm giá trị thay vì đặt trước, bạn chỉ cần gọi số Concat ngược lại. (Ví dụ: GetData().Concat(GetHeaders());)

Nếu GetHeaders() trả về một mảng chuỗi đơn, cá nhân tôi có lẽ muốn quấn nó trong một mảng yếu tố duy nhất thay vì một danh sách:

var all = (new[] {GetHeaders()}).Concat(GetData()); 
+0

GetHeaders() trả về 'string [] ', GetData() trả về' IEnumerable '. Bạn đã đọc câu hỏi của tôi chưa? –

+0

@Gabe: Điều này sẽ làm việc với chuỗi [] và IEnumerable - mảng triển khai IEnumerable . Nếu chuỗi của bạn [] là ** chuỗi **, tuy nhiên, mọi thứ có một chút khác biệt. Câu hỏi của bạn không rõ ràng ở đây. –

+0

@Reed right, tôi đã nhận xét trước khi tôi nói chỉnh sửa của bạn –

1

Rx chứa phương thức StartWith làm tăng giá trị cho chuỗi. Ngoài ra, Return có thể bọc giá trị theo thứ tự để nó có thể được nối thêm thông qua Concat.

 var c = new[] {4}; 
     var c1 = c.StartWith(1, 2, 3); 
     var c2 = c1.Concat(EnumerableEx.Return(5)); 

     c2.Run(Console.Write); // 12345 
0

Một lựa chọn khác là một phương pháp helper mà tạo ra một chuỗi ra khỏi một mặt hàng duy nhất:

public static class EnumerableExt 
{ 
    public static IEnumerable<T> One<T>(T item) 
    { 
     yield return item; 
    } 
} 

... 
//prepend: 
EnumerableExt.One(GetHeaders()).Concat(GetData()); 

//append: 
GetData().Concat(EnumerableExt.One(GetHeaders()); 
Các vấn đề liên quan