2012-08-09 3 views
14

Ich möchte die LINQ TakeWhile Funktion auf LINQ to Objects verwenden. Ich muss jedoch auch das erste Element kennen, das die Funktion "brach", d. H. Das erste Element, bei dem die Bedingung nicht erfüllt war.TakeWhile, aber das Element, das es auch gestoppt

Gibt es eine einzige Funktion, um alle Objekte zu erhalten, die nicht übereinstimmen, plus die erste, die das tut?

Zum Beispiel angesichts der Satz {1,2,3,4,5,6,7,8},

mySet.MagicTakeWhile(x => x != 5); 

=> {1,2,3,4,5}

+0

Sie können eine Methode, wie leicht das schreiben, aber dies wird nicht „faul“, da die Position des letzten Elements, um die nächsten zu bekommen wissen müssen. –

+0

[Diese Frage] (https://stackoverflow.com/q/2242318/241211) ist nicht ganz ein Duplikat, aber teilt [eine Antwort.] (Https://stackoverflow.com/a/6817553/241211) – Michael

Antwort

9

Ich glaube, Sie SkipWhile verwenden können, und nehmen Sie dann das erste Element.

var elementThatBrokeIt = data.SkipWhile(x => x.SomeThing).Take(1); 

UPDATE

Wenn Sie ein einzelnes Erweiterungsmethode möchten, können Sie die folgenden Befehle verwenden:

public static IEnumerable<T> MagicTakeWhile<T>(this IEnumerable<T> data, Func<T, bool> predicate) { 
    foreach (var item in data) { 
     yield return item; 
     if (!predicate(item)) 
      break; 
    } 
} 
+1

Das würde mehrere Anrufe erfordern. Ich könnte einfach 'FirstOrDefault' in diesem Fall tun. –

+0

+1 für die Bereitstellung von Arbeitscode – Gabe

+0

@ Maarten, gute Antwort - Sie können eine Zeile speichern, indem Sie die endgültige 'Ausbeute brechen;' – allonhadaya

6

LINQ to Objects hat kein Betreiber solcher. Aber es ist einfach, eine TakeUntil Erweiterung selbst zu implementieren. Hier ist one such implementation von moreLinq.

+0

Leider enthalten sie dies nicht in der MoreLinq NuGet. Ich werde den Code kopieren und einfügen. Vielen Dank! –

+4

Der Name '' TakeUntil'' vermittelt nicht die Bedeutung. "Nimm'' Eier aus der Schachtel' 'Bis'' Du bekommst einen schlechten, heißt nicht, dass du den schlechten nimmst. – bradgonesurfing

+0

@bradgonesurfing TakeUntilInclusive? –

0

Just for fun:

var a = new[] 
    { 
     "two", 
     "three", 
     "four", 
     "five", 
    }; 
    Func<string, bool> predicate = item => item.StartsWith("t");  
    a.TakeWhile(predicate).Concat(new[] { a.SkipWhile(predicate).FirstOrDefault() }) 
+0

Dies dauert auch zwei Funktionsaufrufe. Sie könnten auch die 'SkipWhile' überspringen und direkt nach' a.FirstOrDefault (Prädikat) 'gehen. –

Verwandte Themen