Powershell在循环中获取枚举器
Powershell get enumerator in loop
我试图在循环散列时获取枚举数 table。
我确实理解它在 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 的解释。
如果在 运行 循环之前将键收集到数组中,则可以在 运行 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
,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 哈希表来解决这个问题,这也允许您使用位置索引 - 但请注意,位置索引然后 returns 条目值,不是键:
$test = [ordered] @{set01 = '0'; set02 = '1'}
for ($i = 0; $i -lt $test.Count; $i++) {
$test[$i]
}
注意:虽然您可以使用$test.Keys[$i]
访问键,如,直接枚举键foreach ($key in $test.Keys)
更简洁,更快;对 $test.Keys[$i]
使用基于索引的迭代的唯一好理由是,如果索引 $i
不仅仅是一个 helper 变量,而是操作所必需的,例如至于输出同时反映键及其索引的字符串。
因此上面的结果是:
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
我试图在循环散列时获取枚举数 table。
我确实理解它在 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
情况下有效?
编辑: 阅读
我想出的一个解决方法是提取循环位置的密钥部分链接到
如果在 运行 循环之前将键收集到数组中,则可以在 运行 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
,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 哈希表来解决这个问题,这也允许您使用位置索引 - 但请注意,位置索引然后 returns 条目值,不是键:
$test = [ordered] @{set01 = '0'; set02 = '1'}
for ($i = 0; $i -lt $test.Count; $i++) {
$test[$i]
}
注意:虽然您可以使用$test.Keys[$i]
访问键,如foreach ($key in $test.Keys)
更简洁,更快;对 $test.Keys[$i]
使用基于索引的迭代的唯一好理由是,如果索引 $i
不仅仅是一个 helper 变量,而是操作所必需的,例如至于输出同时反映键及其索引的字符串。
因此上面的结果是:
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