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,但开启了一些有趣的可能性。

您正在创建一个 散列表,无法使用位置 索引 访问其条目(01, ...);相反,您在 [...] 中指定的是条目 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