2010-11-20 80 views
27

假設我有數組string[] weekDays = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };,我想找出包含's'的數組元素的索引。我如何使用Linq來做到這一點?如何使用Linq在Where子句後選擇數組索引?

我試過int[] indexOfDaysContainingS = weekDays.Where(day => day.Contains("s")).Select((day, index) => index).ToArray();,但是這會返回0,1,2,因爲它可能是在Where()子句之後獲得過濾0123'的索引。如果我把Select()放在第一位,那麼我所擁有的僅僅是索引,並且不能過濾日期。

我需要改變什麼才能使其工作並返回1,2,3而不是?

+0

我知道這不是問題的一部分,但爲什麼不使用for循環代替Linq來做到這一點。你會節省很多分鐘的開發。 – 2010-11-20 11:17:07

回答

34

你可以這樣來做:

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

不知道這是否是最佳..

+1

+1。爲了清晰起見而重新格式化;希望你不介意。 – Ani 2010-11-20 10:48:44

+0

@Ani - 謝謝。我想我應該在去之前正確地醒來:) – Patko 2010-11-20 10:52:33

+0

@Patko但它是如何知道從數組中獲取索引並將其與您在索引屬性中放置的「索引」相關聯? – 2014-04-05 19:05:42

15

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(); 
+0

感謝您的選擇。有沒有什麼理由爲什麼性能會有所不同,使用你的第一個替代方案與Patko對大型陣列的答案?我不確定哪個是最佳選擇。 – mikel 2010-11-20 11:03:14

+1

@ miket2e:Patko的答案是一般的 - 「範圍」方法對於非列表序列不起作用;所以很難做出「公平」的比較。對於數組,我會*認爲''Range'方法會更快 - 有可能*更少的堆分配,它可能*更多的緩存友好等(注意黃鼠狼的話)。不要相信我,衡量! *也許*你甚至不應該在這裏使用LINQ。 – Ani 2010-11-20 11:07:39

+1

(使用統計員減少1個) – Ani 2010-11-20 11:23:32

-1

這應該工作:

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

使用代碼格式化工具並解釋您的答案 – NSNoob 2016-02-23 07:32:12

+0

我不相信這個例子中的邏輯是正確的,因爲返回的索引值應該在收集已被過濾之後而不是相對於原始索引採集。 – 2017-10-03 21:15:33