web-dev-qa-db-de.com

So wählen Sie Werte aus einem Liste mit LINQ innerhalb eines angegebenen Indexbereichs aus

Ich bin ein LINQ-Neuling, der versucht, Folgendes zu erreichen:

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] mit LINQ vergleichen. Ich habe die Erweiterungsmethoden LINQ Select und Take sowie die SelectMany-Methode ausprobiert, aber ich kann nicht herausfinden, wie ich etwas sagen soll 

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

Ich habe mir auch die Contains-Erweiterungsmethode angesehen, aber das sieht nicht, was ich will. Irgendwelche Vorschläge? Vielen Dank.

57
Punit Vora

Verwenden Sie Skip dann Take.

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

(from p in intList.Skip(x).Take(n) select p).sum()
83
Adam Sills

Sie können GetRange () verwenden

list.GetRange(index, count);
32
Onuralp

Bei größeren Listen kann eine separate Erweiterungsmethode für die Leistung geeigneter sein. Ich weiß, dass dies für den ursprünglichen Fall nicht notwendig ist, aber die Implementierung von Linq (für Objekte) hängt von der Iteration der Liste ab. Für große Listen könnte dies (sinnlos) teuer sein. Eine einfache Erweiterungsmethode, um dies zu erreichen, könnte sein:

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++;
    }
}
17
Tao

So filtern Sie nach bestimmten Indizes (nicht von-bis):

public static class ListExtensions
{
   public static IEnumerable<TSource> ByIndexes<TSource>(this IList<TSource> source, params int[] indexes)
   {        
        if (indexes == null || indexes.Length == 0)
        {
            foreach (var item in source)
            {
                yield return item;
            }
        }
        else
        {
            foreach (var i in indexes)
            {
                if (i >= 0 && i < source.Count)
                    yield return source[i];
            }
        }
   }
}

Zum Beispiel:

string[] list = {"a1", "b2", "c3", "d4", "e5", "f6", "g7", "h8", "i9"};
var filtered = list.ByIndexes(5, 8, 100, 3, 2); // = {"f6", "i9", "d4", "c3"};
0
stomy