2016-08-22 2 views
1

Ich habe eine Liste von Zeichenketten wie:einfach traditionelle foreach zu Linq FürJeden

[email protected] 
[email protected] 
[email protected];[email protected];[email protected] 
[email protected] 
[email protected] 

Ich möchte es wollen, wie:

[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 

Also habe ich den Code unten geschrieben und es funktioniert wie erwartet .

foreach (var email in emailAddressesOnRequest) 
{ 
    if (!string.IsNullOrEmpty(email) && email.Contains(';')) 
    { 
     emailAddressesOnRequest.AddRange(email.Split(';').ToList()); 
     emailAddressesOnRequest.Remove(email); 
    } 
} 

Gibt es eine Möglichkeit, es einfach zu LINQ ForEach?

+5

'List.ForEach' ist nicht LINQ, es ist eine Methode, die bereits vor LINQ existierte. –

+0

Wie man es LINQ ForEach dann macht? –

+1

Haben Sie bemerkt, dass Ihre 'foreach' eine Ausnahme auslöst, wenn Sie die Liste während der Aufzählung ändern? Sie können es beheben, indem Sie verwenden: 'foreach (var E-Mail in emailAddressesOnRequest.ToList()) {...}' –

Antwort

5

Was Sie suchen, ist, durch die Sammlung zu iterieren und für jedes Element ein Element einer anderen Art zurückzugeben. Dazu verwenden Sie Select.

Da Sie in Ihrem Fall möglicherweise von jedem Objekt eine Sammlung von Elementen zurückgeben möchten und sie nicht in verschachtelten Sammlungen haben möchten, verwenden Sie SelectMany für das Ergebnis der Split(';') Methode.

List<string> values = new List<string> 
{ 
    "[email protected]", 
    "[email protected]", 
    null, 
    "[email protected]; mnop @domain.com; qrst @domain.com", 
    "[email protected]", 
    "[email protected]" 
}; 

var result = values.Where(value => !string.IsNullOrWhiteSpace(value)) 
        .SelectMany(value => value.Split(';')).ToList(); 

Und in Abfragesyntax:

var result = (from value in values 
      where !string.IsNullOrWhiteSpace(value) 
      from email in value.Split(';') 
      select email).ToList(); 
+1

OP verwendet 'string.IsNullOrEmpty', so kann es möglicherweise Null sein. Abgesehen von dieser netten und einfachen Lösung. –

+0

@TimSchmelter - True :) bearbeitet –

+0

besser wäre Null-Werte weglassen, er entfernt sie auch nicht aus der Liste. Aber ich denke, es wird überhaupt nicht benötigt, wenn die Liste keine Nullen enthalten kann. –

1
var query = from line in emailAddressesOnRequest 
      where !String.IsNullOrEmpty(line) 
      from email in line.Split(';') 
      select email; 
1

Was sehr geholfen mich ling zu verstehen The standard LINQ operators

war Wenn Sie jede Zeichenfolge in Teil durch Semikolon teilen, erhalten Sie eine Sammlung von String-Sequenzen oder einem IEnumerable<IEnumerable<string>>

Die IEnumareable Erweiterungsfunktion, um sie in eine IEnumerable<string> umzuwandeln ist Enumerable.SelectMany. Wenn über einen SelectMany Iterieren ist es, wie Sie eine verschachtelte foreach tun:

List<string[]> listOfStringArrays = ... 
List<string> outputList = new List<string>(); 
foreach (string[] stringArray in listOfStringArrays) 
{ 
    foreach (string str in stringArray) 
    { 
     outputList.Add(str); 
    } 
} 

In Ihrem Beispiel die innere foreach erfolgt AddRange verwenden.

Mit Select und Split konvertieren Sie Ihre Sammlung von Strings in eine Sequenz von String-Sequenzen. SelectMany wird es eine Reihe von Strings machen:

IEnumerable<string> myInputStrings = ... 
IEnumerable<string> outputStrings = inputStrings 
    .Select(inputString => inputString.Split(';')) 
    .SelectMany(splitResult => splitResult); 

Die Select jeder der inputStrings nehmen, und teilen Sie sie durch ein Semikolon. Die Ausgabe ist ein String-Array, das IEnumerable<string> implementiert, auch wenn Ihre Eingabe kein Semikolon hatte.

Die verkettet jede Zeichenfolge Sequenz Ihrer Zeichenfolge Sequenzen. Das Ergebnis ist eine Folge von Strings.

Um in ein Array oder eine Liste zu konvertieren, verwenden Sie ToArray() oder ToList().