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

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

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:

$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])"
}

The result I was expecting was:

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

The result I'm actually getting is:

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

What am I doing wrong?

答案1

得分: 3

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

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

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

$result = foreach ($list1Item in $list1)
{
    foreach ($list2Item in $list2)
    {
        Write-Output ($list1Item, $list2Item) -NoEnumerate
    }
}

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

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

$result = foreach ($list1Item in $list1)
{
    foreach ($list2Item in $list2)
    {
        ,@($list1Item, $list2Item)
      # ^
      # 前置逗号充当一元数组运算符
    }
}

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

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

$result = foreach ($list1Item in $list1)
{
    foreach ($list2Item in $list2)
    {
        # 这会创建一个标量对象,这里没有什么可以展开的
        [pscustomobject]@{
          Item1 = $list1Item
          Item2 = $list2Item
        }
    }
}

foreach ($resultItem in $result)
{
    Write-Host "$($resultItem.Item1)-$($resultItem.Item2)"
}

请参阅 关于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:

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

$result = foreach ($list1Item in $list1)
{
    foreach ($list2Item in $list2)
    {
        Write-Output ($list1Item, $list2Item) -NoEnumerate
    }
}

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:

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

$result = foreach ($list1Item in $list1)
{
    foreach ($list2Item in $list2)
    {
        ,@($list1Item, $list2Item)
      # ^
      # prefixed comma acts as a unary array operator
    }
}

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

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

$result = foreach ($list1Item in $list1)
{
    foreach ($list2Item in $list2)
    {
        # this creates a scalar object, nothing to unroll here
        [pscustomobject]@{
          Item1 = $list1Item
          Item2 = $list2Item
        }
    }
}

foreach ($resultItem in $result)
{
    Write-Host "$($resultItem.Item1)-$($resultItem.Item2)"
}

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:

确定