2010-08-20 7 views
24

Wenn ich zwei Sequenzen habe und ich beide zusammen verarbeiten will, kann ich sie vereinigen und weg gehen wir.Gibt es einen besseren linq Weg zu "Union" ein einzelnes Element?

Jetzt sagen wir, ich habe ein einzelnes Element, das ich zwischen den zwei Sequenzen verarbeiten möchte. Ich kann es schaffen, indem ich ein Array mit einem einzigen Gegenstand erstelle, aber gibt es einen besseren Weg? das heißt

var top = new string[] { "Crusty bread", "Mayonnaise" }; 
string filling = "BTL"; 
var bottom = new string[] { "Mayonnaise", "Crusty bread" }; 

// Will not compile, filling is a string, therefore is not Enumerable 
//var sandwich = top.Union(filling).Union(bottom); 

// Compiles and works, but feels grungy (looks like it might be smelly) 
var sandwich = top.Union(new string[]{filling}).Union(bottom); 

foreach (var item in sandwich) 
    Process(item); 

Gibt es eine genehmigt Art und Weise, dies zu tun, oder ist dies die genehmigte Art und Weise?

Dank

+1

Dies ist, wie ich neige dazu, es zu tun .. nicht glücklich fühlen, aber nie dachte, es wert war, um Arbeit .. Frage mich, ob es einen Weg gibt eine implizite Konvertierung zu schreiben zwischen T-und T-Array .. –

+0

mögliche Duplikat von [Lieblings-Weg, um eine neue IEnumerable Sequenz von einem einzigen Wert zu erstellen?] (http://StackOverflow.com/Questions/1019737/favorite-way-to-create-an- new-iienerablet-sequence-from-a-single-Wert) – nawfal

+1

Sie können den Union-Ausdruck nur ein bisschen vereinfachen, indem Sie new string [] auf nur new [] reduzieren. Sonst ist Jon Hannas Lösung wahrscheinlich der beste Weg, dies zu tun, wenn man so etwas oft macht. –

Antwort

32

Eine Möglichkeit ist es, sich zu überlasten:

public static IEnumerable<T> Union<T>(this IEnumerable<T> source, T item) 
{ 
    return source.Union(Enumerable.Repeat(item, 1)); 
} 

Das ist, was wir mit Concat in MoreLINQ tat.

+1

Enumerable.Repeat, perfekt, danke. Ich könnte diese Überlastung tatsächlich nutzen, danke. –

+1

Für zusätzliche Nerdiness, nennen Sie die Überladung 'Cons': D –

+2

Hin und wieder, wenn ich C# -Code schreiben, ich sehne mich nach der Operation Operator aus Sprachen wie F # oder LISP. Syntax wie 'list :: item' oder' list1 @ list2' sind in der Regel gut lesbar, sobald Sie sich daran gewöhnt haben. – LBushkin

1

Ich neige dazu, die folgenden irgendwo in meinem Code haben:

public static IEnumerable<T> EmitFromEnum<T>(this T item) 
{ 
    yield return item; 
} 

Es ist zwar nicht so sauber ist col.Union(obj.EmitFromEnum()); wie col.Union(obj) zu nennen es bedeutet, dass diese einzelne Erweiterungsmethode alle anderen Fälle abdeckt, möchte ich könnte so ein einzelnes -item Aufzählung.

+1

'public static IEnumerable EmitFromEnum (dieses T-Stück) { Rendite-Item; } ' –

+0

@KuganKumar Yup. Vielen Dank. –

5

Betrachten wir noch flexibler Ansatz:

public static IEnumerable<T> Union<T>(this IEnumerable<T> source, params T[] items) 
{ 
    return source.Union((IEnumerable<T>)items); 
} 

Werke für einzelne sowie mehrere Artikel. Sie können auch null source Werte annehmen:

public static IEnumerable<T> Union<T>(this IEnumerable<T> source, params T[] items) 
{ 
    return source != null ? source.Union((IEnumerable<T>)items) : items; 
} 
Verwandte Themen