2016-02-04 31 views
1

我最近遇到一些情况,它让我想知道是否有任何方法获得内部索引,或者如果没有,可以在使用LINQ时有效地生成索引。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另一组项目,并从中挑选的结果。现在

,我想知道是否有任何替代方案,做的更简单的方法,如:

  1. 如果有任何(内置)的方式获得了IEnumerable的内部指标不宣用let或
  2. 来使用Enumerable.Range以外的东西(可能类似于新的东西?我不太熟悉怎么做)为IEnumerable生成索引,或者可以缩短代码的任何其他东西但仍然获得IEnumerable的索引。
+4

var result = list.Select((x,idx)=> idx);其中idx是IEnumerable中每个元素的索引 - 如果我误解了道歉。 – TVOHM

+0

@TVOHM感谢您的评论,你可能是正确的......这是我从来没有意识到的重载之一之一.. – Ian

回答

2

IEnumerable.Select with indexHow to get index using LINQ?,等等:IEnumerable<T>.Select()overload that provides an index

利用这一点,您可以:

  1. 项目到一个匿名类型(或Tuple<int, T>如果你想暴露在其他方法,匿名类型是本地)包含索引和值。
  2. 过滤您要查找的值的结果。
  3. 只项目索引。

因此,代码如下所示:

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>时,生成的索引将无法用于索引字典。

+0

这对我来说是新的。我不知道Select有超载提供索引。但是我听说IEnumerable不一定是命令?但是我们仍然可以通过这样做来获得索引? – Ian

+0

“这取决于spurce收藏。”如在...?有些集合不能被订购(使用您提供的解决方案),因此无法索引,但有些可以?我们如何知道那些可以被索引的,哪些不可以? – Ian

+1

好的,谢谢你的澄清和输入。这对我确实很有用。 – Ian