2010-06-23 24 views
5

Ich versuche einen LINQ-Ausdruck zu finden, um zwei Listenelemente zu vergleichen.Vergleichen Sie zwei Listenelemente mit LINQ

Was ich tun möchte, ist:

List<int> _int = new List<int> { 1, 2, 3, 3, 4, 5}; 
_int.Where(x => x == _int[(_int.IndexOf(x)) + 1]); 

leider nur die letzte +1 springt aus dem Bereich der Liste.

Wie kann ich ein Element mit dem nächsten in der Liste in einem LINQ-Ausdruck vergleichen?

Antwort

6

Nicht so schön, aber sollte funktionieren.

list.Where((index, item) => index < list.Count - 1 && list[index + 1] == item) 

Oder das Folgende.

list.Take(list.Count - 1).Where((index, item) => list[index + 1] == item) 
+0

Bei "index, item" ist etwas schief gelaufen (ich musste sie umschalten), aber deine erste Lösung funktioniert und es ist kein Zähler draußen! Vielen Dank. – Gpx

4
int i = 0; 
_int.Where(x => 
{ 
    i++; 
    return i < _int.Length && x == _int[i]; 
}); 
+0

Hat das nicht das gleiche Problem mit dem letzten Element? –

+0

Nein, weil && ein Kurzschlussoperator ist. Das heißt, wenn i <_int.Length ist, wird x == _int [i] nicht ausgewertet. – Odrade

+0

@Odrade, der ursprüngliche Kommentar war vor der Überprüfung gegen die Länge wurde bearbeitet. –

0

Wenn Sie es wirklich mit einem Lambda-Ausdruck tun wollen, einen gebundenen Scheck hinzufügen (das entweder immer das letzte Element zurückgibt oder nicht, Ihre Wahl).

Ein iterativer Ansatz wäre jedoch besser lesbar, IMO.

1

Es ist ein interessantes Problem, würde ich vielleicht für die Suche nach Ausdruck Syntax gehen, wo es wie folgt

int[] array = {1,2,3,3,4,5}; 
var query = from item in array.Select((val, index) => new { val, index }) 
      join nextItem in array.Select((val, index) => new { val, index }) 
      on item.index equals (nextItem.index + 1) 
      where item.val == nextItem.val 
      select item.val; 

getan werden kann, die drei aus dem Array extrahieren würde (oder Liste). Was natürlich im Abfrageausdruck getan werden kann, kann natürlich in Lambda gemacht werden.

Bearbeiten Joels Lösung ist viel einfacher als meine und wenn Sie es nur brauchen, um auf einer Liste oder einem Array zu arbeiten, ist es perfekt. Wenn Sie etwas flexibleres benötigen, um gegen IEnumerable zu arbeiten, dann sollten Sie etwas wie das oben genannte anstreben (oder etwas, das offensichtlich besser ist).

2
List<int> _int = new List<int> { 1, 2, 3, 3, 4, 5 }; 
Enumerable.Range(0, _int.Count - 1) 
    .Select(i => new {val = _int[i], val2 = _int[i + 1]}) 
    .Where(check => check.val == check.val2) 
    .Select(check => check.val);