鉴于此输入:
$values = @(1, @(2, 3), $null, @(@(4), 5), 6)
在
上创建干净的迭代/管道有什么必要1,2,3,4,5,6
条件:
$null
。加成:
[1,2,3,4,5,6]
ConvertTo-Json -Compress
我已经看过Flatten array in PowerShell,那里的解决方案似乎不符合条件。
答案 0 :(得分:6)
@(1, @(2, 3), $null, @(@(4), 5), 6) | %{$_} | ?{$_ -ne $null}
输出:
1
2
3
4
5
6
默认情况下,ForEach-Object
cmdlet(%
)会对数组进行展平。
答案 1 :(得分:3)
为了完整起见,因为它可以帮助另一个用户,我想要包含一个非常简单的递归函数,它涵盖了除了...之外的大多数条件。
最好是干净且令人难忘的,即非拜占庭式的管道操作首选,如果可能的话,不依赖于自定义功能。
我知道 [你]本可以做到[你的]自己但也许它可以帮助别人。在谈到PowerShell时,我已经看到过这种情况,称为展开数组。如果你继续搜索,这个词可能有助于结出更多的果实。
使用$input
我们的意图,我们做了一个相当简单的功能。如果传递的元素之一是数组元素,那么我们再次调用该函数,直到我们将其缩减为原始值。
function Flatten-Array{
$input | ForEach-Object{
if ($_ -is [array]){$_ | Flatten-Array}else{$_}
} | Where-Object{![string]::IsNullorEmpty($_)}
# | Where-Object{$_} would also work.
}
所以样本调用将是
@(1, @(2, 3), $null, @(@(4), 5), 6) | Flatten-Array | ConvertTo-Json -Compress
哪个网[1,2,3,4,5,6]
。 $null
涵盖了几个简单Where
条款之一。
答案 2 :(得分:3)
您可以使用递归命令执行此操作:
$values = (1, (2, 3), $null, (,4, 5), 6)
$values|&{
process{
if($null -ne [System.Management.Automation.LanguagePrimitives]::GetEnumerator($_)){
$_|&$MyInvocation.MyCommand.ScriptBlock
}elseif($null -ne $_){
$_
}
}
}
但你应该确定,你没有传递这样的信息作为输入:
$values[0]=$values=,0
答案 3 :(得分:1)
注意:不要使用$input
作为变量名称,它是一个自动管道枚举器,它不会按照您的预期行事。< / p>
两轮流水线操作(即使用ForEach-Object
)将为您展平该结构,ConvertTo-Json -Compress
将自动省略$null
值:
PS C:\> $NestedArray = @(1, @(2, 3), $null, @(@(4), 5), 6)
PS C:\> $FlatArray = $NestedArray | ForEach-Object { $_ } | ForEach-Object { $_ }
PS C:\> $FlatArray | ConvertTo-Json -Compress
[1,2,3,4,5,6]
答案 4 :(得分:1)
这是一个不使用管道传输的递归Flatten-Array
函数:
$values = @(1, @(2, 3), $null, @(@(4), 5), 6)
function Flatten-Array{
param (
[array] $inputArray
)
foreach ($item in $inputArray){
# skip $nulls
if ($item -ne $null) {
# recurse for arrays
if ($item.gettype().BaseType -eq [System.Array]) {
Flatten-Array $item
}
else {
# output non-arrays
$item
}
}
}
}
Flatten-Array $values | %{$_.gettype()}