Как выбрать значения в указанном диапазоне индекса из списка с помощью LINQ - PullRequest
60 голосов
/ 25 июня 2009

Я новичок LINQ, пытаюсь использовать его для достижения следующих целей:

У меня есть список целых: -

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

Теперь я хочу сравнить сумму первых трех элементов [диапазон индекса 0-2] с последними тремя [диапазон индекса 3-5], используя LINQ. Я попробовал методы расширения LINQ Select и Take, а также метод SelectMany, но я не могу понять, как сказать что-то вроде

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

Я тоже посмотрел на метод расширения Contains, но он не видит, как получить то, что я хочу. Какие-либо предложения? Спасибо.

Ответы [ 4 ]

88 голосов
/ 25 июня 2009

Использовать Пропустить , затем взять.

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

(from p in intList.Skip(x).Take(n) select p).sum()
34 голосов
/ 10 июля 2013

Вы можете использовать GetRange ()

list.GetRange(index, count);
17 голосов
/ 06 июня 2011

Для больших списков отдельный метод расширения может быть более подходящим для производительности. Я знаю, что это не обязательно для начального случая, но реализация Linq (для объектов) опирается на итерацию списка, поэтому для больших списков это может (бессмысленно) дорого. Простой метод расширения для достижения этой цели может быть:

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 голосов
/ 13 апреля 2018

Для фильтрации по определенным индексам (не от-до):

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];
            }
        }
   }
}

Например:

string[] list = {"a1", "b2", "c3", "d4", "e5", "f6", "g7", "h8", "i9"};
var filtered = list.ByIndexes(5, 8, 100, 3, 2); // = {"f6", "i9", "d4", "c3"};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...