如何在PowerShell中将数组添加到管道

huangapple go评论81阅读模式
英文:

How to add an array to pipeline in PowerShell

问题

$list1 = 'A','B';
$list2 = '1','2';

$result = foreach ($list1Item in $list1)
{
foreach ($list2Item in $list2)
{
($list1Item, $list2Item)
}
}

foreach ($resultItem in $result)
{
Write-Host "$($resultItem[0])-$($resultItem[1])"
}

我预期的结果是:

A-1
A-2
B-1
B-2

我实际得到的结果是:

A-
1-
A-
2-
B-
1-
B-
2-

我做错了什么?

英文:

I'm trying to combine two arrays into an array of arrays in PowerShell. Here's my script:

  1. $list1 = 'A','B';
  2. $list2 = '1','2';
  3. $result = foreach ($list1Item in $list1)
  4. {
  5. foreach ($list2Item in $list2)
  6. {
  7. ($list1Item, $list2Item)
  8. }
  9. }
  10. foreach ($resultItem in $result)
  11. {
  12. Write-Host "$($resultItem[0])-$($resultItem[1])"
  13. }

The result I was expecting was:

  1. A-1
  2. A-2
  3. B-1
  4. B-2

The result I'm actually getting is:

  1. A-
  2. 1-
  3. A-
  4. 2-
  5. B-
  6. 1-
  7. B-
  8. 2-

What am I doing wrong?

答案1

得分: 3

PowerShell的默认行为是展开可枚举的输出,这就是为什么最终得到一个“扁平”数组的原因。

您可以通过使用 Write-Output -NoEnumerate 来避免这种行为:

  1. $list1 = 'A','B';
  2. $list2 = '1','2';
  3. $result = foreach ($list1Item in $list1)
  4. {
  5. foreach ($list2Item in $list2)
  6. {
  7. Write-Output ($list1Item, $list2Item) -NoEnumerate
  8. }
  9. }

另一个选择是构造一个文字嵌套数组 - 这样管道处理器将展开第一维,然后您将得到数组对象:

  1. $list1 = 'A','B';
  2. $list2 = '1','2';
  3. $result = foreach ($list1Item in $list1)
  4. {
  5. foreach ($list2Item in $list2)
  6. {
  7. ,@($list1Item, $list2Item)
  8. # ^
  9. # 前置逗号充当一元数组运算符
  10. }
  11. }

或者您可以构造一些不可枚举的东西,比如每一对的对象:

  1. $list1 = 'A','B';
  2. $list2 = '1','2';
  3. $result = foreach ($list1Item in $list1)
  4. {
  5. foreach ($list2Item in $list2)
  6. {
  7. # 这会创建一个标量对象,这里没有什么可以展开的
  8. [pscustomobject]@{
  9. Item1 = $list1Item
  10. Item2 = $list2Item
  11. }
  12. }
  13. }
  14. foreach ($resultItem in $result)
  15. {
  16. Write-Host "$($resultItem.Item1)-$($resultItem.Item2)"
  17. }

请参阅 关于about_Pipelines 帮助主题 以进一步讨论这种行为。

英文:

PowerShell's default behavior is to unroll enumerable output, which is why you end up with a "flat" array.

You can circumvent this behavior by using Write-Output -NoEnumerate:

  1. $list1 = 'A','B';
  2. $list2 = '1','2';
  3. $result = foreach ($list1Item in $list1)
  4. {
  5. foreach ($list2Item in $list2)
  6. {
  7. Write-Output ($list1Item, $list2Item) -NoEnumerate
  8. }
  9. }

Another option is to construct a literal nested array - then the pipeline processor will unroll the first dimension and you're left with array objects:

  1. $list1 = 'A','B';
  2. $list2 = '1','2';
  3. $result = foreach ($list1Item in $list1)
  4. {
  5. foreach ($list2Item in $list2)
  6. {
  7. ,@($list1Item, $list2Item)
  8. # ^
  9. # prefixed comma acts as a unary array operator
  10. }
  11. }

Or you can construct something that isn't enumerable, like an object for each pair:

  1. $list1 = 'A','B';
  2. $list2 = '1','2';
  3. $result = foreach ($list1Item in $list1)
  4. {
  5. foreach ($list2Item in $list2)
  6. {
  7. # this creates a scalar object, nothing to unroll here
  8. [pscustomobject]@{
  9. Item1 = $list1Item
  10. Item2 = $list2Item
  11. }
  12. }
  13. }
  14. foreach ($resultItem in $result)
  15. {
  16. Write-Host "$($resultItem.Item1)-$($resultItem.Item2)"
  17. }

See the about_Pipelines help topic for further discussion on this behavior

huangapple
  • 本文由 发表于 2023年6月26日 20:18:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76556624.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定