我意识到存在相关问题,但所有答案似乎都是解决问题的核心问题。 powershell是否有一个可以使用scriptblock将数组元素聚合为单个值的操作?这在其他语言中称为aggregate
或reduce
或fold
。
我可以很容易地自己编写它,但鉴于它是任何列表处理的基本操作,我会假设有一些我不知道的东西。
所以我正在寻找的是像这样的东西
1..10 | Aggregate-Array {param($memo, $x); $memo * $x}
答案 0 :(得分:30)
没有任何明显命名为Reduce-Object的东西,但你可以用Foreach-Object实现你的目标:
1..10 | Foreach {$total=1} {$total *= $_} {$total}
BTW还没有Join-Object根据某些匹配属性合并两个数据序列。
答案 1 :(得分:7)
这是我想要开始一段时间的事情。看到这个问题,只写了一个pslinq
(https://github.com/manojlds/pslinq)实用程序。现在的第一个也是唯一一个cmdlet是Aggregate-List
,可以像下面这样使用:
1..10 | Aggregate-List { $acc * $input } -seed 1
#3628800
和:
1..10 | Aggregate-List { $acc + $input }
#55
字符串反转:
"abcdefg" -split '' | Aggregate-List { $input + $acc }
#gfedcba
PS:这是一个更多的实验
答案 2 :(得分:5)
如果你需要最大值,最小值,总和或平均值,你可以使用Measure-Object
遗憾地它不会处理任何其他聚合方法。
Get-ChildItem | Measure-Object -Property Length -Minimum -Maximum -Average
答案 3 :(得分:1)
最近陷入了类似的问题。这是一个纯粹的Powershell解决方案。不像Javascript版本那样处理数组和字符串中的数组,但可能是一个很好的起点。
function Reduce-Object {
[CmdletBinding()]
[Alias("reduce")]
[OutputType([Int])]
param(
# Meant to be passed in through pipeline.
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True)]
[Array] $InputObject,
# Position=0 because we assume pipeline usage by default.
[Parameter(Mandatory=$True,
Position=0)]
[ScriptBlock] $ScriptBlock,
[Parameter(Mandatory=$False,
Position=1)]
[Int] $InitialValue
)
begin {
if ($InitialValue) { $Accumulator = $InitialValue }
}
process {
foreach($Value in $InputObject) {
if ($Accumulator) {
# Execute script block given as param with values.
$Accumulator = $ScriptBlock.InvokeReturnAsIs($Accumulator, $Value)
} else {
# Contigency for no initial value given.
$Accumulator = $Value
}
}
}
end {
return $Accumulator
}
}
1..10 | reduce {param($a, $b) $a + $b}
# Or
reduce -inputobject @(1,2,3,4) {param($a, $b) $a + $b} -InitialValue 2
答案 4 :(得分:0)
https://github.com/chriskuech/functional上有一个功能模块,它具有一个reduce对象,merge对象,test-equality等。Powershell具有map(foreach-object)和filter(where-object)令人惊讶),但不能减少。 https://medium.com/swlh/functional-programming-in-powershell-876edde1aadb甚至javascript也减少了数组。减速器实际上非常强大。您可以根据它定义地图和过滤器。
1..10 | reduce-object { $a * $b }
3628800
测量对象不能求和[时间跨度]:
1..10 | % { [timespan]"$_" } | Reduce-Object { $a + $b } | ft
Days Hours Minutes Seconds Milliseconds
---- ----- ------- ------- ------------
55 0 0 0 0
合并两个对象:
@{a=1},@{b=2} | % { [pscustomobject]$_ } | Merge-Object -Strategy fail
b a
- -
2 1