71

我是一个 LINQ 新手,试图用它来实现以下目标:

我有一个整数列表:-

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

现在,我想使用 LINQ 比较前三个元素 [索引范围 0-2] 与后三个 [索引范围 3-5] 的总和。我尝试了 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

5 回答 5

107

使用跳过然后采取。

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

(from p in intList.Skip(x).Take(n) select p).sum()
于 2009-06-25T03:54:25.127 回答
40

您可以使用 GetRange()

list.GetRange(index, count);
于 2013-07-10T11:11:16.723 回答
18

对于较大的列表,单独的扩展方法可能更适合性能。我知道这对于初始情况不是必需的,但是 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++;
    }
}
于 2011-06-05T21:07:03.750 回答
1

按特定索引(不是从到到)过滤:

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"};
于 2018-04-12T21:17:53.840 回答
1

从 .NET 6 开始,可以对 Take 方法使用范围语法

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

// Starting from index 0 (including) to index 3 (excluding) will select indexes (0, 1, 2)
Console.WriteLine(intList.Take(0..3).Sum()); // {1, 2, 3} -> 6

// By default is first index 0 and can be used following shortcut.
Console.WriteLine(intList.Take(..3).Sum());  // {1, 2, 3} -> 6      


// Starting from index 3 (including) to index 6 (excluding) will select indexes (3, 4, 5)
Console.WriteLine(intList.Take(3..6).Sum()); // {3, 2, 1} -> 6  

// By default is last index lent -1 and can be used following shortcut.
Console.WriteLine(intList.Take(3..).Sum());  // {3, 4, 5} -> 6

// Reverse index syntax can be used. Take last 3 items.
Console.WriteLine(intList.Take(^3..).Sum()); // {3, 2, 1} -> 6

// No exception will be raised in case of range is exceeded.
Console.WriteLine(intList.Take(^100..1000).Sum()); 

简单地说,intList.Take(..3).Sum()可以intList.Take(3..).Sum()与 .NET 6 一起使用。

于 2021-12-17T11:33:47.293 回答