Лучше поздно, чем никогда.
Я пришел к следующему методу (код представляет собой смесь PowerShell 2.0 и PowerShell 3.0):
if(-not (test-path variable:psversiontable)){return}
rv -ea silentlycontinue -force *
cls
$major=$psversiontable.psversion.major
$linqenum=[linq.enumerable]
'min:'+$linqenum::min([int[]](170..180))
'max:'+$linqenum::max($linqenum::range(170,170))
$membertypes=[reflection.membertypes]
$bindflags=[reflection.bindingflags]
[reflection.membertypes]$type=$membertypes::method
[reflection.bindingflags]$attr=$bindflags::public,$bindflags::static
$name='Min'
$methods=$linqenum.getmember($name,$type,$attr)|?{$_.isgenericmethod}
$method=$methods[0]
$closed=$method.makegenericmethod((,[int]))
"$name`:"+$closed.Invoke($null,(,[int[]](170..180)))
$name='Max'
$methods=$linqenum.getmember($name,$type,$attr)|?{$_.isgenericmethod}
$method=$methods[0]
$closed=$method.makegenericmethod((,[int]))
"$name`:"+$closed.Invoke($null,(,$linqenum::range(170,170)))
$name='SelectMany'
$methods=$linqenum.getmember($name,$type,$attr)|?{$_.isgenericmethod}
$method=$methods[0]
#$params=[hashtable],[string]
#$closed=$method.makegenericmethod($params)
$closed=$method.makegenericmethod(([hashtable],[string]))
[hashtable[]]$owners=@{name="Sidney";pets=("Scruffy","Sam")},
@{name="Ronen";pets=("Walker","Sugar")},
@{name="Hines";pets=(,"Dusty")},
@{name="Vernette";pets=("Scratches","Diesel")}
if($major -eq 2){
$delegate=[func[hashtable,collections.generic.ienumerable[string]]]
$sb={param([hashtable]$owner) ,[string[]]$owner.pets}
}else{
$delegate=[func[hashtable,string[]]]
$sb={param($owner) $owner.pets}
}
$selector=$sb -as $delegate
$params=$owners,$selector
$pets=$closed.Invoke($null,$params)
"`n$name`n$('-'*$name.length)"
$pets
$method=$methods[3]
$params=[hashtable],[string],[hashtable]
$closed=$method.makegenericmethod($params)
$resultsb={param($owner,$pet)@{owner=$owner.name;pet=$pet}}
#$resultdelegate=[func[hashtable,string,hashtable]]
#$result=$resultsb -as $resultdelegate
$params=$owners,$selector,[func[hashtable,string,hashtable]]$resultsb
$ownerpet=$closed.Invoke($null,$params)
$ownerpet|select values|ft -auto
if($major -gt 2){
$linqenum::selectmany(
$owners,
[func[hashtable,string[]]]`
{param($owner) $owner.pets},
[func[hashtable,string,hashtable]]`
{param($owner,$pet)@{owner=$owner.name;pet=$pet}}
)|select values|ft -auto
$linqenum::selectmany(
[int[]](1..4),
[func[int,int[]]]`
{param($left) 11..(11+$left-1)},
[func[int,int,hashtable]]`
{param($left,$right)@{left=$left;right=$right}}
)|select values|ft -auto
$linqenum::selectmany(
$linqenum::range(1,4),
[func[int,int[]]]`
{param($left) $linqenum::range(11,$left)},
[func[int,int,hashtable]]`
{param($left,$right)@{left=$left;right=$right}}
)|select values|ft -auto
$name='Join'
[hashtable[]]$person=@{id=1;name='ivan'},@{id=2;name='vasilij'},@{id=3;name='pjotr'}
[hashtable[]]$job=@{id=1;job='tokar'},@{id=1;job='pekar'},
@{id=2;job='doctor'},
@{id=3;job='soldat'},@{id=3;job='milicioner'},@{id=3;job='jurist'}
"`n$name`n$('-'*$name.length)"
[linq.enumerable]::join(
$person,$job,
[func[hashtable,int]]{param($p) $p.id},
[func[hashtable,int]]{param($p) $p.id},
[func[hashtable,hashtable,hashtable]]`
{param($p,$j) @{name=$p.name;job=$j.job}}
)|select values|ft -auto
}