Powershell在循环中获取枚举器

时间:2019-04-06 13:29:41

标签: powershell hashtable enumeration

我试图在循环哈希表时获取枚举数。

我确实了解它如何在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,但带来了一些有趣的可能性。

2 个答案:

答案 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 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 哈希表来解决此问题,这也允许您使用位置索引-但是请注意,位置索引会返回条目 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

虽然它的内存效率较低,因为必须首先整体创建索引数组,所以通常不必担心。