我想在PowerShell中压缩两个数组,类似于Ruby如何实现, 这里有一个假设的操作符(我知道我们可能在谈论某种古怪的管道,但我只是想展示一个示例输出)。
PS> @(1, 2, 3) -zip @('A', 'B', 'C')
@(@(1, 'A'), @(2, 'B'), @(3, 'C'))
PS> @(1, 2, 3) -zip @('A', 'B', 'C')
@(@(1, 'A'), @(2, 'B'), @(3, 'C'))
目前没有内置的功能,自己编写函数也不建议。因此,我们将采用LINQ Zip方法并对其进行封装。
[System.Linq.Enumerable]::Zip((1, 2, 3), ('A', 'B', 'C'), [Func[Object, Object, Object[]]]{ ,$args })
这个方法可以用,但长期使用并不方便。我们可以对函数进行封装(并将其包含在我们的配置文件中?)。
function Select-Zip {
[CmdletBinding()]
Param(
$First,
$Second,
$ResultSelector = { ,$args }
)
[System.Linq.Enumerable]::Zip($First, $Second, [Func[Object, Object, Object[]]]$ResultSelector)
}
而你可以简单地称之为:
PS> Select-Zip -First 1, 2, 3 -Second 'A', 'B', 'C'
1
A
2
B
3
C
使用非默认结果选择器:
PS> Select-Zip -First 1, 2, 3 -Second 'A', 'B', 'C' -ResultSelector { param($a, $b) "$a::$b" }
1::A
2::B
3::C
我将管道版本留给聪明的读者作为练习 :)
PS> 1, 2, 3 | Select-Zip -Second 'A', 'B', 'C'
foreach
_语句_的增强,类似于foreach ($elementFromArray1, $elementFromArray2 in @(1, 2, 3), @('A', 'B', 'C')) { ... }
- 不幸的是,它被拒绝了 - 参见GitHub问题#14732。 - mklement0Linq.Enumerable.Zip
重载,输出元组,从而减轻了传递函数的需要:[Linq.Enumerable]::Zip( [int[]](1, 2, 3), [string[]]('A', 'B', 'C'))
。请注意,数组必须是有类型的,否则 PowerShell 将无法找到正确的重载。 - zett42[object[]]
数组也可以起到作用:[Linq.Enumerable]::Zip( [object[]](1, 2, 3), [object[]]('A', 'B', 'C') )
。 - zett42[Linq.Enumerable]::Zip($arr1, $arr2)
。 - dudeNumber4# Multiple arrays
$Sizes = @("small", "large", "tiny")
$Colors = @("red", "green", "blue")
$Shapes = @("circle", "square", "oval")
# The first line "zips"
$Sizes | ForEach-Object { $i = 0 }{ @{size=$_; color=$Colors[$i]; shape=$Shapes[$i]}; $i++ } `
| ForEach-Object { $_.size + " " + $_.color + " " + $_.shape }
输出:
small red circle
large green square
tiny blue oval