【问题标题】:foreach loops: How to update collection variable within loop?foreach 循环:如何在循环内更新集合变量?
【发布时间】:2018-12-25 05:25:20
【问题描述】:

有没有办法改变循环的集合变量不能从其循环内更新并在下一次迭代中使用新值的行为?

例如:

$items = @(1,1,1,2)
$counter = 0

foreach ($item in $items) {
    $counter += 1
    Write-Host "Iteration:" $counter " | collection variable:" $items
    $item
    $items = $items | Where-Object {$_ -ne $item}
}

$counter

如果您运行此代码,循环将执行多次。 但是,由于第一次迭代时 $items1,1,1,2 更改为仅包含 2,因此循环应该只运行一次。

我怀疑这是因为集合变量 $items 没有在 foreach 部分更新。

有没有办法解决这个问题?

【问题讨论】:

  • foreach ($item in $items)改成foreach ($item in $items.Length),你会看到预期的结果。
  • Write-Host "Iteration:" $counter " | collection variable:" $items 这行对我来说似乎有点坏了。与您的问题无关,但您可以简化这一点,我敢肯定
  • 你想要完成什么?这感觉像是 X/Y 问题。
  • @colonel_claypoo 我认为您在这里混淆了观察到的行为,引用Length 不会更改$items 的类型(BaseType 必须更改)。 WRT 你的问题,你不能在迭代集合时修改它。请解释一下您要完成的工作
  • @mklement0:由于我的问题范围比我在这里提出的问题更大,我创建了一个新的question

标签: powershell loops foreach


【解决方案1】:

您不能将foreach 循环与循环主体中正在修改的集合一起使用。

尝试这样做实际上会导致错误 (Collection was modified; enumeration operation may not execute.)

没有看到错误的原因是您实际上并没有修改原始集合本身;您将 new 集合实例分配给相同的变量,但这与枚举的原始集合实例无关。

您应该改用while 循环,在这种情况下,$items 变量引用在每次迭代中都会重新计算:

$items = 1, 1, 1, 2
$counter = 0

while ($items) { # Loop as long as the collection has at last 1 item.
  $counter += 1
  Write-Host "Iteration: $counter | collection variable: $items"
  $item = $items[0] # access the 1st element
  $item # output it
  $items = $items | Where-Object {$_ -ne $item} # filter out all elements with the same val.
}

现在您只得到 2 次迭代:

Iteration: 1 | collection variable: 1 1 1 2
1
Iteration: 2 | collection variable: 2
2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    • 2019-08-21
    • 2016-09-26
    相关资源
    最近更新 更多