2010-11-20 10 views
27

Angenommen, ich habe das Array string[] weekDays = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };, und ich möchte den Index der Array-Elemente mit 's' herausfinden. Wie kann ich das mit Linq machen?Wie Array-Index nach Where-Klausel mit Linq auswählen?

Ich habe versucht int[] indexOfDaysContainingS = weekDays.Where(day => day.Contains("s")).Select((day, index) => index).ToArray();, aber dies gibt 0,1,2 zurück, da es vermutlich den Index der gefilterten IEnumberable<string> nach der Where() -Klausel statt. Wenn ich zuerst Select() setze, dann habe ich nur den Index und kann nicht nach Tagen filtern.

Was muss ich ändern, damit es funktioniert und 1,2,3 zurückgibt?

+0

Ich weiß, das ist nicht Teil der Frage, aber warum don‘ t verwenden Sie dies mit einer for-Schleife anstelle von Linq. Sie hätten viele Minuten Entwicklungszeit gespart. –

Antwort

34

Man könnte es auf diese Weise tun:

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

nicht sicher, ob dies optimal ist ..

+1

+1. Aus Gründen der Klarheit umformatiert; Ich hoffe, es macht Ihnen nichts aus. – Ani

+0

@Ani - Danke. Ich denke, ich sollte aufwachen, bevor ich zu SO ging :) – Patko

+0

@Patko, aber wie wusste es, den Index aus dem Array zu nehmen und es mit dem "Index" zu verknüpfen, den Sie in die Eigenschaft Index setzen? –

15

Patko Antwort ist die Art und Weise im allgemeinen Fall zu gehen.

Hier gibt es 2 weitere Optionen:

// 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(); 

Mit 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

Danke für die Alternativen. Gibt es irgendeinen Grund, warum die Leistung anders wäre, wenn man die erste Alternative vs Patkos Antwort für ein großes Array verwendet? Ich bin mir nicht sicher, welches die optimale Wahl ist. – mikel

+1

@ miket2e: Patkos Antwort ist die allgemeine - der 'Range'-Ansatz funktioniert nicht gut mit Nicht-Listen-Sequenzen; Es ist also schwer, einen "fairen" Vergleich zu machen. Für Arrays würde ich denken, dass der 'Range'-Ansatz schneller wäre - es gibt * wahrscheinlich * weniger Heap-Allokation, es ist * möglicherweise * mehr cache-freundlich usw. (beachten Sie die Weasel-Wörter). Glauben Sie mir nicht, messen Sie! * Vielleicht * solltest du LINQ hier nicht benutzen. – Ani

+1

(1 weniger Enumerator) – Ani

-1

Dies sollte funktionieren:

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

Verwenden Sie Code-Formatierungstool und erklären Sie Ihre Antwort – NSNoob

+0

Ich glaube nicht, dass die Logik in diesem Beispiel korrekt ist, da der Index zurückgegeben werden soll, nachdem die Sammlung bereits gefiltert wurde und nicht den Index relativ zum Original Sammlung. –

Verwandte Themen