我正在尝试在循环哈希表时获取枚举器。
我确实理解它在foreach
循环中是如何工作的,如下所示:
$test = @{set01 = '0'; set02 = '1'}
foreach ($t in $test.GetEnumerator()) {
Write-Host 'key: '$t.Key
}
哪个会循环输出单个键:
key: set02
key: set01
我想知道是否可以在C类型循环中执行此操作,例如:
$test = @{set01 = '0'; set02 = '1'}
for ($i = 0; $i -lt 1; $i++) {
Write-Host 'key: '$test.Keys[$i] # edited with Dandré's answer.
}
其中列出了所有键:
key: set02 set01
key:
这是可能的还是.GetEnumerator()
只能在foreach
情况下工作?
编辑:阅读mklement0's答案我发现它不是直接可能的。我会将其标记为详细解释的答案。
我想出一个解决方法来提取循环位置的关键字部分链接到Dandré's答案结合mklement0的解释。
如果在运行循环之前将密钥收集到数组中,则可以在运行for循环时查找它们。
$test = @{set01 = '0'; set02 = '1'}
$keys = @($test.Keys)
for ($i = 0; $i -lt $test.Count; $i++) {
Write-Host 'key:'$keys[$i]
}
这将按预期结果:
key: set02
key: set01
根据数组,键需要首先逆转[array]::Reverse($keys)
。
$keys
变量也可以在循环中用于调用特定键,如:$test[$keys[$i]]
。这有点像黑客,但开启了一些有趣的可能性。
您正在创建一个哈希表,无法使用位置索引访问其条目(0
,1
,...);相反,你在[...]
中指定的是一个输入键。
因此,使用.Keys
属性进行枚举:
$test = @{set01 = '0'; set02 = '1'}
foreach ($key in $test.Keys) {
$key
# To access the entry's *value*, use $test[$key] $test[$key]
}
结果是:
set02
set01
请注意密钥的枚举方式与定义的顺序不同,因为[hashtable]
实例不保证任何特定的枚举顺序。
在PSv3 +中,您可以使用有序的哈希表来解决这个问题,这也可以让您使用位置索引 - 但请注意,位置索引会返回条目值,而不是键:
$test = [ordered] @{set01 = '0'; set02 = '1'}
for ($i = 0; $i -lt $test.Count; $i++) {
$test[$i]
}
注意:虽然你可以使用$test.Keys[$i]
来访问密钥,就像在Dandre's answer中一样,使用foreach ($key in $test.Keys)
直接枚举密钥不那么冗长和快速;使用$test.Keys[$i]
进行基于索引的迭代的唯一理由是,如果索引$i
不仅仅是一个辅助变量,而且是操作所必需的,例如输出反映键及其索引的字符串。
因此上述产量:
0
1
请注意,for
语法不仅详细,它实际上比foreach
表现更差,如果你确实需要显式索引,请使用foreach
和通过范围运算符生成的索引(..
),这不仅更快,而且可以说更具可读性比for
循环:
$test = [ordered] @{set01 = '0'; set02 = '1'}
foreach ($i in 0..($test.Count-1)) {
$test[$i]
}
虽然它的内存效率较低,但由于索引数组必须作为一个整体预先创建,因此通常不需要考虑。
同意@ mklement0。如果你想要传统的for
循环,你可以使用Keys
属性执行以下操作。
$test = @{set01 = '0'; set02 = '1'}
for ($i = 0; $i -lt $test.Count; $i++) {
Write-Host $test.Keys[$i]
}
这将输出:set02 set01