如何使用 LINQ 从 List 中选择提供索引范围内的值

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

我有一个 int 列表:-

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

现在,我想使用 LINQ 比较前三个元素[索引范围0-2]和最后三个[索引范围3-5]的和。我尝试了 LINQSelect 和 Take 扩展方法以及 SelectMany 方法,但是我不知道如何说

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

我也查看了 Contains 扩展方法,但是它并没有得到我想要的结果。有什么建议吗?谢谢。

74916 次浏览

使用 斯吉普然后采取。

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


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

对于较大的列表,单独的扩展方法可能更适合于性能。我知道对于初始情况来说这是不必要的,但是 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++;
}
}

可以使用 GetRange ()

list.GetRange(index, count);

通过特定的索引(不是 from-To)进行筛选:

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

从.NET 6开始,可以使用 范围语法 for 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一起使用。