如何在使用 Linq 的 Where 子句之后选择数组索引?

Posted

技术标签:

【中文标题】如何在使用 Linq 的 Where 子句之后选择数组索引?【英文标题】:How to select array index after Where clause using Linq? 【发布时间】:2010-11-20 10:37:44 【问题描述】:

假设我有数组 string[] weekDays = "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ; ,我想找出包含 's' 的数组元素的索引。如何使用 Linq 做到这一点?

我试过int[] indexOfDaysContainingS = weekDays.Where(day => day.Contains("s")).Select((day, index) => index).ToArray();,但这会返回0,1,2,因为它可能是在Where() 子句之后获取过滤后的IEnumberable<string> 的索引。如果我把 Select() 放在第一位,那么我所拥有的只是索引并且不能按天过滤。

我需要进行哪些更改才能使其正常工作并返回1,2,3

【问题讨论】:

我知道这不是问题的一部分,但为什么不使用 for 循环而不是 Linq。您会节省很多时间的开发时间。 【参考方案1】:

你可以这样做:

weekDays.Select((day, index) => new  Day = day, Index = index )
        .Where(x => x.Day.Contains("s"))
        .Select(x => x.Index)
        .ToArray();

不确定这是否最佳..

【讨论】:

@Ani - 谢谢。我想我应该在去 SO 之前好好醒来 :) @Patko 但它是如何知道从数组中获取索引并将其与您放入 Index 属性中的“索引”相关联的? @YonatanNir, Select 有两个重载,一个还有一个元素的索引作为参数,参见msdn.microsoft.com/en-us/library/bb534869.aspx。然后将该索引参数保存到一个匿名对象中,以便可以在第二个Select 中再次使用它。我希望这能回答你的问题?【参考方案2】:

Patko 的回答是一般情况下要走的路。

这里还有 2 个选项:

// Idea only works with collections that can be accessed quickly by index.
int[] indices = Enumerable.Range(0, weekDays.Length)
                          .Where(index => weekDays[index].Contains("s"))
                          .ToArray();

与MoreLinq:

// Similar to Patko's idea, except using a 'named' type.
int[] indices = weekDays.AsSmartEnumerable()
                        .Where(item => item.Value.Contains("s"))
                        .Select(item => item.Index)
                        .ToArray();

【讨论】:

感谢您提供的替代方案。使用您的第一个替代方案与 Patko 对大型阵列的回答有什么不同的原因吗?我不确定哪个是最佳选择。 @miket2e:Patko 的回答是一般性的——Range 方法不适用于非列表序列;所以很难做出“公平”的比较。对于数组,我认为 Range 方法会更快 - 可能 更少的堆分配,它可能 对缓存更友好等。 (注意黄鼠狼的话)。不信,量一下! 也许你甚至不应该在这里使用 LINQ。【参考方案3】:

这应该可行:

weekDays.Where(a => a.Contains("s")).Select((a, i) => i).ToArray();

【讨论】:

我不认为这个例子中的逻辑是正确的,因为返回的索引值应该是在集合已经被过滤之后,而不是相对于原始集合的索引。

以上是关于如何在使用 Linq 的 Where 子句之后选择数组索引?的主要内容,如果未能解决你的问题,请参考以下文章

Linq to entity 没有生成 where 子句

Linq to Entities 中的动态 where 子句 (OR)

LINQ to SQL Where 子句可选条件

C# 使用带有 where 子句的 Linq 查询作为 dataTable 上的变量

如何使用 linq lambda 扩展方法执行带有 where 子句的左外连接

如何在 LINQ where 子句中传递 func 表达式?