2009-06-25 5 views
50

ich ein LINQ Neuling bin versucht, es zu benutzen folgendes acheive:Wie aus einer Liste Wert innerhalb eines vorgesehenen Indexbereiches wählen LINQ mit

Ich habe eine Liste von Ints: -

List<int> intList = new List<int>(new int[]{1,2,3,3,2,1}); 

Nun möchte ich die Summe der ersten drei Elemente [Indexbereich 0-2] mit den letzten drei [Indexbereich 3-5] unter Verwendung von LINQ vergleichen. Ich versuchte, die LINQ Select und Erweiterungsmethoden nehmen sowie die Select Methode, aber ich kann nicht herausfinden, wie etwas zu sagen, wie

(from p in intList 
where p in Take contiguous elements of intList from index x to x+n 
select p).sum() 

Ich schaute auf der Erweiterungsmethode zu Enthält, aber das nicht sieht, zu erhalten ich was ich will. Irgendwelche Vorschläge? Vielen Dank.

Antwort

77

Verwenden Sie Skip dann Take.

yourEnumerable.Skip(4).Take(3).Select(x=>x) 

(from p in intList.Skip(x).Take(n) select p).sum() 
+6

Beachten Sie, dass Liste .GetRange wird für größere Sammlungen obwohl effizienter sein: https: // icodeit. wordpress.com/2012/08/27/performance-of-skip-and-take-in-linq-to-objects/, http://geekswithblogs.net/BlackRabbitCoder/archive/2012/03/29/c.net -little-wonders-skip-and-take.aspx – nawfal

+0

Das ist ein guter, gültiger Kommentar (so gültig vor ein paar Jahren hatte ich den Autor der Antwort unten, der das gleiche sagte, upvoted), obwohl das OP speziell über LINQ so gefragt du kannst es nicht wiederholen y garantieren Sie eine Liste als Ihre Quelle. Dies könnte eine vereinfachte Version des eigentlichen Problems gewesen sein, wobei die vereinfachte Version nur eine hartcodierte Liste war (und könnte tatsächlich eine Abfrage auf einem Objektgraphen oder einer LINQ to SQL-Abfrage sein). –

15

Für größere Listen könnte eine separate Erweiterungsmethode für die Leistung geeigneter sein. Ich weiß, dass dies für den ersten Fall nicht notwendig ist, aber die Implementierung von Linq (zu Objekten) beruht auf der Wiederholung der Liste, so dass dies für große Listen (sinnlos) teuer sein könnte. Eine einfache Erweiterung Methode, dies zu erreichen sein könnte:

public static IEnumerable<TSource> IndexRange<TSource>(
    this IList<TSource> source, 
    int fromIndex, 
    int toIndex) 
{ 
    int currIndex = fromIndex; 
    while (currIndex <= toIndex) 
    { 
     yield return source[currIndex]; 
     currIndex++; 
    } 
} 
+0

Danke, du hast meinen Tag gemacht! –

26

Sie können GetRange verwenden()

list.GetRange(index, count); 
+1

Wo ist diese Funktion? .NET 4.5 oder so? –

+4

@AdamNofsinger Dies ist unter System.Collections.Generic Namespace. Es kam mit .Net 2.0. http://msdn.microsoft.com/en-us/library/21k0e39c(v=vs.80).aspx – Onuralp