2009-06-25 6 views
50

Jestem nowicjuszem LINQ próbuje go używać do acheive następujące:Jak wybrać wartości w podanym zakresie indeksu z listy za pomocą LINQ

Mam listę wskazówki: -

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

Teraz chcę porównać sumę pierwszych trzech elementów [zakres indeksu 0-2] z ostatnimi trzema [zakres indeksu 3-5] przy użyciu LINQ. Próbowałem LINQ Select i Take metody rozszerzenie, jak również metody SelectMany, ale nie mogę dowiedzieć się, jak powiedzieć coś

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

Spojrzałem na Zawiera metodę rozszerzenia też, ale że nie widzi, aby uzyskać mi, czego chcę. Jakieś sugestie? Dzięki.

Odpowiedz

77

Użyj Skip, a następnie Take.

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

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

Zauważ, że Lista .GetRange będzie bardziej skuteczne, choć w przypadku większych zbiorów: 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

To jest dobry, poprawny, komentarz (tak ważny kilka lat temu wznowiłem autor odpowiedzi poniżej, który powiedział to samo), chociaż PO zapytał konkretnie o LINQ tak nie możesz się odwołać y gwarantujemy listę jako źródło. Mogła to być uproszczona wersja prawdziwego problemu, o którym mowa, gdzie uproszczona wersja była tylko zakodowaną listą (i tak naprawdę może być zapytaniem na wykresie obiektowym lub zapytaniu LINQ do SQL). –

15

Dla większych list, osobna metoda rozszerzenia może być bardziej odpowiednia dla wydajności. Wiem, że nie jest to konieczne w początkowym przypadku, ale implementacja Linq (do obiektów) polega na iteracji listy, więc w przypadku dużych list może to być (bezcelowo) kosztowne. Prosta metoda rozszerzenie do osiągnięcia tego celu mogą być:

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

Dzięki, zrobiłeś mój dzień! –

26

Można użyć GetRange()

list.GetRange(index, count); 
+1

Gdzie jest ta funkcja? .NET 4.5 czy coś takiego? –

+4

@AdamNofsinger Jest to w przestrzeni nazw System.Collections.Generic. Przyszedł z .Net 2.0. http://msdn.microsoft.com/en-us/library/21k0e39c(v=vs.80).aspx – Onuralp

Powiązane problemy