我最近遇到过一些情况,它让我想知道是否有任何方法可以获得内部索引,或者如果没有,在使用LINQ时有效地生成索引。
考虑以下情况:
List<int> list = new List() { 7, 4, 5, 1, 7, 8 };
在C#中,如果我们要使用LINQ在上面的数组上返回索引“7”,我们不能简单地使用IndexOf / LastIndexOf - 因为它只会返回第一个/最后一个结果。
这不起作用:
var result = list.Where(x => x == 7).Select(y => list.IndexOf(y));
然而,我们有几种解决方法。
例如,有一种方法可以做到这一点(我通常这样做):
int index = 0;
var result = from x in list
let indexNow = index++
where x == 7
select indexNow;
它将使用let。
引入附加参数indexNow另一种方式:
var result = Enumerable.Range(0, list.Count).Where(x => list.ElementAt(x) == 7);
它将使用Enumerable.Range生成另一组项目并从中选择结果。
现在,我想知道是否有其他更简单的方法,例如:
答案 0 :(得分:2)
来自IEnumerable.Select with index,How to get index using LINQ?,依此类推:IEnumerable<T>.Select()
有一个overload that provides an index。
使用此功能,您可以:
Tuple<int, T>
,如果要将其公开给其他方法,匿名类型是本地的),其中包含索引和值。所以代码看起来像这样:
var result = list.Select((v, i) => new { Index = i, Value = v })
.Where(i => i.Value == 7)
.Select(i => i.Index);
现在result
将包含一个包含所有索引的枚举。
请注意,这仅适用于保证插入顺序并提供数字索引器的源集合类型,例如List<T>
。当您将其用于Dictionary<TKey, TValue>
或HashSet<T>
时,生成的索引将无法用于索引字典。