86 votes

Obtenir l'index de l'élément courant dans une boucle PowerShell

Étant donné une liste d'éléments dans PowerShell, comment puis-je trouver l'index de l'élément actuel à l'intérieur d'une boucle ?

Par exemple :

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

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

Le but de tout cela est de sortir une collection en utilisant Format-Tableau et ajouter une colonne initiale avec l'index de l'élément courant. De cette façon, les gens peuvent choisir de manière interactive un élément à sélectionner.

76voto

Keith Hill Points 73162

.NET dispose de quelques méthodes utilitaires pratiques pour ce genre de choses dans System.Array :

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

De bons points sur l'approche ci-dessus dans les commentaires. Outre le fait de trouver "simplement" l'indice d'un élément dans un tableau, étant donné le contexte du problème, cette approche est probablement plus adaptée :

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

Foreach (%) peut avoir un sciptblock Begin qui s'exécute une fois. Nous y définissons une variable d'index et nous pouvons ensuite la référencer dans le bloc de script de traitement où elle est incrémentée avant de quitter le bloc de script.

11 votes

De plus, vous ne voulez probablement pas chercher chaque indice d'un élément du tableau tout en itérant ces éléments. Il s'agirait d'une recherche linéaire pour chaque élément, ce qui semble faire d'une itération O(n^2) :-)

0 votes

IndexOf fonctionne si vous êtes sûr d'avoir toujours un tableau, mais la fonction $letters | % {$i=0}... est sûre même si $letters finit par être un seul objet et non un tableau.

68voto

Cédric Rup Points 5363

Je ne suis pas sûr que ce soit possible avec une variable "automatique". Vous pouvez toujours en déclarer une pour vous-même et l'incrémenter :

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

Ou utilisez un for boucle à la place...

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

0 votes

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

0 votes

Ça a marché comme un charme quand j'ai dû renommer des fichiers avec un compteur~. dir | % {$i = 46}{ move-item $_ ("ARM-{0:00000}.pdf" -f $i++)}

1 votes

Le site $letters | % {$counter... est sûre même si $letters n'est qu'un seul objet et non un tableau, alors que l'élément for ne gère pas cela correctement.

57voto

Chrissy LeMaire Points 1074

Pour PowerShell 3.0 et plus, il y en a un intégré :)

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

16voto

Shay Levy Points 41404
0..($letters.count-1) | foreach { "Value: {0}, Index: {1}" -f $letters[$_],$_}

0 votes

C'est assez propre, mais c'est dommage qu'il n'y ait pas de méthode directe qui n'implique pas la recherche de l'index dans le tableau.

-3voto

Justin Grote Points 67

Pour ceux qui, comme moi, viennent de Google, les versions ultérieures de Powershell comportent une fonction $foreach variable automatique. Vous pouvez trouver l'objet "courant" avec $foreach.Current

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X