mjolinor's answer ist konzeptuell elegant, aber langsam mit großen Arrays, was vermutlich auf einen ersten eine parallele Anordnung von Indizes zu bauen (die auch speicher ineffizient ist).
Es ist vom Konzept her ähnlich die folgenden LINQ-basierte Lösung (PSV3 +), die speichereffizienter und etwa doppelt so schnell ist, aber immer noch langsam:
$arr = 'A','D','B','D','C','E','D','F'
[Linq.Enumerable]::Where(
[Linq.Enumerable]::Range(0, $arr.Length),
[Func[int, bool]] { param($i) $arr[$i] -eq 'D' }
)
Während jedes Powershell Looping Lösung ist letztlich langsam im Vergleich zu einer kompilierten Sprache, die folgende Alternative, während ausführlicher, ist immer noch viel schneller mit großen Arrays:
PS C:\> & { param($arr, $val)
$i = 0
foreach ($el in $arr) { if ($el -eq $val) { $i } ++$i }
} ('A','D','B','D','C','E','D','F') 'D'
1
3
6
Hinweis:
Vielleicht überraschend, dass diese Lösung ist sogar schneller als Matt's solution, die [array]::IndexOf()
in einer Schleife ruft stattdessen alle Elemente aufzuzählen.
Verwendung eines Skriptblock (mit Call Operator &
und Argumenten aufgerufen), die zwar nicht unbedingt erforderlich ist, wird verwendet, die Verschmutzung der umgebenden Gültigkeitsbereich mit Helfer Variable $i
zu verhindern.
Die foreach
Anweisung ist schneller als die Foreach-Object
Cmdlets (dessen integrierten Aliase sind %
und verwirrender, auch foreach
).
Einfach (implizit) Ausgabe $i
für jede Übereinstimmung macht PowerShell sammeln mehrere Ergebnisse in einem Array.
- Wenn nur ein Index gefunden wird, erhalten Sie eine skalare
[int]
Instanz erhalten statt; Umgehen Sie den gesamten Befehl in @(...)
, um sicherzustellen, dass Sie immer ein Array erhalten.
Während $i
selbst den Wert von $i
, ++$i
nach Design gibt nicht (obwohl Sie (++$i)
das erreichen nutzen könnten, falls erforderlich).
Im Gegensatz zu Array.IndexOf()
, die Powershell -eq
Operator ist Fall- unempfindlich standardmäßig; Für Groß-/Kleinschreibung verwenden Sie stattdessen -ceq
.
Es ist einfach, die oben in eine (einfache) Funktion (beachten Sie, dass die Parameter sind absichtlich nicht typisiert, für Flexibilität) zu drehen:
function get-IndicesOf($Array, $Value) {
$i = 0
foreach ($el in $Array) {
if ($el -eq $Value) { $i }
++$i
}
}
# Sample call
PS C:\> get-IndicesOf ('A','D','B','D','C','E','D','F') 'D'
1
3
6
wenn niemand kommt mit einer besseren Lösung Sie könnten einfach eine for-Schleife verwenden, passen Sie hinein und erhalten Sie Ihren Index von der Zählervariable – Paul
@Paul Das ist genau was ich vermeiden wollte: P – ALIENQuake