如何在使用 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 Entities 中的动态 where 子句 (OR)
C# 使用带有 where 子句的 Linq 查询作为 dataTable 上的变量