【问题标题】:Implicit Index or Generating Index in LINQLINQ 中的隐式索引或生成索引
【发布时间】:2016-02-04 19:04:01
【问题描述】:

我最近遇到了几个案例,这让我想知道在使用 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 生成索引,或者
  3. 任何其他可以缩短代码但仍能获得 IEnumerable 索引的东西。

【问题讨论】:

  • var result = list.Select((x, idx) =&gt; idx); 其中 idx 是 IEnumerable 中每个元素的索引 - 如果我有误解,我们深表歉意。
  • @TVOHM 感谢您的评论,您很可能是对的......这是我迄今为止从未意识到的重载之一......

标签: c# indexing ienumerable


【解决方案1】:

IEnumerable.Select with indexHow to get index using LINQ? 等等:IEnumerable&lt;T&gt;.Select() 有一个overload that provides an index

使用它,您可以:

  1. 投影到包含索引和值的匿名类型(或 Tuple&lt;int, T&gt;,如果您想将其公开给其他方法,匿名类型是本地的)。
  2. 过滤这些结果以获得您正在寻找的值。
  3. 仅投影索引。

所以代码将如下所示:

var result = list.Select((v, i) => new { Index = i, Value = v })
                 .Where(i => i.Value == 7)
                 .Select(i => i.Index);

现在result 将包含一个包含所有索引的枚举。

请注意,这仅适用于保证插入顺序并提供数字索引器的源集合类型,例如 List&lt;T&gt;。当您将其用于 Dictionary&lt;TKey, TValue&gt;HashSet&lt;T&gt; 时,生成的索引将无法用于索引到字典中。

【讨论】:

  • 这对我来说是新的。我不知道 Select 有提供索引的重载。但是听说IEnumerable不一定是有序的?但是我们仍然可以通过这样做获得索引吗?
  • "这取决于 spence 集合。"如..?有些集合不能这样订购(使用您提供的解决方案),因此不能被索引,但有些可以?我们如何知道哪些可以被索引,哪些不能?
  • 好的,感谢您的澄清和输入。确实对我有用。
猜你喜欢
  • 1970-01-01
  • 2022-10-25
  • 2013-07-11
  • 1970-01-01
  • 2020-12-03
  • 2018-01-13
  • 1970-01-01
  • 2021-10-22
  • 1970-01-01
相关资源
最近更新 更多