2009-11-23 15 views
45

Dato un elenco di elementi in PowerShell, come faccio a trovare l'indice dell'articolo corrente all'interno di un ciclo?Ottieni l'indice dell'elemento corrente nel ciclo PowerShell?

Ad esempio:

$letters = { 'A', 'B', 'C' } 

$letters | % { 
# Can I easily get the index of $_ here? 
} 

Lo scopo di tutto questo è che voglio uscita una raccolta utilizzando Format-Table e aggiungi una colonna iniziale con l'indice della voce corrente. In questo modo le persone possono scegliere in modo interattivo un oggetto da selezionare.

risposta

20

Non sono sicuro che sia possibile con una variabile "automatica". Si può sempre dichiarare uno per te e incrementarlo

$letters = { 'A', 'B', 'C' } 
$letters | % {$counter = 0}{...;$counter++} 

o utilizzare un ciclo for invece ...

for ($counter=0; $counter -lt $letters.Length; $counter++){...} 
+0

Esempio: '> "A, B, C, D, E, F, G" -split "" | % {$ i = 0} {if ($ i -gt 3) {$ _}; ++ $ i} 'Output:' E F G' – Andrew

+0

Ha funzionato come un incantesimo quando ho dovuto rinominare i file con un contatore ~ ​​'dir | % {$ i = 46} {oggetto-spostamento $ _ ("ARM- {0: 00000} .pdf" -f $ i ++)} ' – Sung

48

.NET ha alcuni metodi di utilità a portata di mano per questo genere di cose in System.Array :

PS> $a = 'a','b','c' 
PS> [array]::IndexOf($a, 'b') 
1 
PS> [array]::IndexOf($a, 'c') 
2 

Buoni punti sull'approccio sopra nei commenti. Oltre a "solo" trovare un indice di un elemento di un array, dato il contesto del problema, questo è probabilmente più adatto:

$letters = { 'A', 'B', 'C' } 
$letters | % {$i=0} {"Value:$_ Index:$i"; $i++} 

foreach (%) può avere una sciptblock che esegue una volta Begin. Impostiamo qui una variabile index e quindi possiamo fare riferimento al processo scripblock dove viene incrementato prima di uscire dallo scriptblock.

+3

Potrebbe esserci un problema se l'array contiene duplicati ... –

+5

Anche tu probabilmente non voglio cercare ogni indice di un elemento dell'array mentre itera questi elementi. Sarebbe una ricerca lineare per ogni oggetto; sembra di fare un'iterazione O (n^2) :-) – Joey

8
0..($letters.count-1) | foreach { "Value: {0}, Index: {1}" -f $letters[$_],$_} 
+0

Questo è abbastanza pulito, ma è troppo male non esiste un metodo diretto che non implichi la ricerca dell'indice nell'array. –

26

C'è un costruito in :)

foreach ($item in $array) { 
    $array.IndexOf($item) 
} 
+0

Probabilmente questo è stato inserito in una versione più recente di PS rispetto a quella in uso nel 2009, altrimenti questa dovrebbe essere la risposta accettata ora. –

+0

Hai perfettamente ragione. La domanda originale è stata posta un mese dopo l'uscita di PowerShell 2.0 e IndexOf è stato aggiunto in PowerShell 3.0. –

+8

Questo è trovare l'indice del primo elemento corrispondente a ogni elemento dell'array, non iterando con un valore di indice. Questo è più lento, e se la matrice contiene elementi duplicati otterrai gli indici sbagliati. – mdonoughe

Problemi correlati