ale*_*2k8 17 collections powershell
假设我们有:
$a = @(1, @(2, @(3)))
Run Code Online (Sandbox Code Playgroud)
我想变平$a获得@(1, 2, 3).
我找到了一个解决方案:
@($a | % {$_}).count
Run Code Online (Sandbox Code Playgroud)
但也许有更优雅的方式?
ale*_*2k8 10
相同的代码,只包含在函数中:
function Flatten($a)
{
,@($a | % {$_})
}
Run Code Online (Sandbox Code Playgroud)
测试:
function AssertLength($expectedLength, $arr)
{
if($ExpectedLength -eq $arr.length)
{
Write-Host "OK"
}
else
{
Write-Host "FAILURE"
}
}
# Tests
AssertLength 0 (Flatten @())
AssertLength 1 (Flatten 1)
AssertLength 1 (Flatten @(1))
AssertLength 2 (Flatten @(1, 2))
AssertLength 2 (Flatten @(1, @(2)))
AssertLength 3 (Flatten @(1, @(2, @(3))))
Run Code Online (Sandbox Code Playgroud)
警告:请参阅最后的编辑!
Powershell v4.0 中引入的数组方法可能.ForEach()可以最优雅地解决这个问题。从性能角度来看,它的优点是不需要构建管道,因此在某些情况下它可能会表现得更好。
> $a.ForEach({$_}).Count
3
Run Code Online (Sandbox Code Playgroud)
如果您已经有管道,则展平数组的最简单方法是将其通过管道传输Write-Output:
> $b = $a | Write-Output
> $b.Count
3
Run Code Online (Sandbox Code Playgroud)
--
编辑:上面的答案并不正确。它不会完全展平具有多个嵌套数组的数组。@SantiagoSquarzon 的答案有一个需要多次展开的深度嵌套数组的示例:
> $toUnroll = @(@(0,1),@(2,3),@(@(4,@(5,6)),@(7,8),9),10) # 11 elements
> $toUnroll.ForEach({$_}).Count
8
> $toUnroll.ForEach({$_}).ForEach({$_}).Count
10
> $toUnroll.ForEach({$_}).ForEach({$_}).ForEach({$_}).Count
11
Run Code Online (Sandbox Code Playgroud)
或者,也许更清楚:
> $toUnroll = @(@(0,1),@(2,3),@(@(4,@(5,6)),@(7,8),9),10) # 11 elements
### Unroll 0 times
> $toUnroll.ForEach({$_ | ConvertTo-Json -Compress})
[0,1]
[2,3]
[[4,[5,6]],[7,8],9]
10
### Unroll 1 times
> $toUnroll.ForEach({$_}).ForEach({$_ | ConvertTo-Json -Compress})
0
1
2
3
[4,[5,6]]
[7,8]
9
10
### Unroll 2 times
> $toUnroll.ForEach({$_}).ForEach({$_}).ForEach({$_ | ConvertTo-Json -Compress})
0
1
2
3
4
[5,6]
7
8
9
10
### Unroll 3 times
> $toUnroll.ForEach({$_}).ForEach({$_}).ForEach({$_}).ForEach({$_ | ConvertTo-Json -Compress})
0
1
2
3
4
5
6
7
8
9
10
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8591 次 |
| 最近记录: |