我试图在循环哈希表时获取枚举数。
我确实了解它如何在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]]
。这有点hack,但带来了一些有趣的可能性。
答案 0 :(得分:3)
同意@ mklement0。
如果您希望使用传统的for
循环,则可以使用Keys
属性进行以下操作。
$test = @{set01 = '0'; set02 = '1'}
for ($i = 0; $i -lt $test.Count; $i++) {
Write-Host $test.Keys[$i]
}
这将输出:set02 set01
答案 1 :(得分:2)
您正在创建一个 hashtable ,其条目不能通过位置 indices (0
,1
,...)访问。相反,您在[...]
中指定的是条目 key 。
因此,请使用.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 +中,您可以使用 ordered 哈希表来解决此问题,这也允许您使用位置索引-但是请注意,位置索引会返回条目 values ,不是键:
$test = [ordered] @{set01 = '0'; set02 = '1'}
for ($i = 0; $i -lt $test.Count; $i++) {
$test[$i]
}
注意:在{em>可以使用$test.Keys[$i]
来访问密钥的过程中,就像在Dandre's answer中一样,使用foreach ($key in $test.Keys)
进行键的直接枚举不那么冗长,而且速度更快;将基于索引的迭代与$test.Keys[$i]
一起使用的唯一好理由是,如果索引$i
不仅是 helper 变量,而且是操作(例如输出)所必需的既反映键又反映其索引的字符串。
因此,上面的结果是:
0
1
请注意, for
语法不仅冗长,实际上还比foreach
差,并且如果您确实需要显式索引,请使用{{ 1}}以及通过范围运算符(foreach
)生成的索引,它比..
循环不仅速度更快,而且可读性更高:
for
虽然它的内存效率较低,因为必须首先整体创建索引数组,所以通常不必担心。