tech.guitarrapc.cóm

Technical updates

PowerShell で 2つのシーケンスから1つのシーケンスを生成したい(1)

公開していないユーティリティがいくつかあるのですが少しだけ記事にします。

みんな大好き LINQ には、 Enumerable.Zip メソッドがあります。

とっても便利で、大変重宝するのですが、これに類する操作が PowerShell にはありません。とはいえ、[LINQ.Enumerable]::Zip() を使おうにもほげーとなるので、似たような処理をPowerShell でやってみます。

目次

なにしたいの

単純に Key と Value のそれぞれのシーケンスを1にして生成したいにょです。この時、Zip同様に 2つのシーケンスの要素数が異なる場合、要素数が少ない方のシーケンス分だけループしてくれるといいですね。

なんかこういうのやりたい時多くないですか?

# sample Key<String>, Value<Int32>
[int[]]$hoge = 1, 2, 3, 4
[string[]]$fuga = "hoge", "moge", "fuga", "piyo"

結果として、

1 hoge                               
2 moge
3 fuga
4 piyo

このようにペアになって1つのシーケンスで出力されるとうれしいです。もちろん、型も保持してですね。

コード

GitHub に置いておきます。

サンプル

いくつか見てみます。

シンプル

先ほどの例ならこのようになります。

# sample Key<String>, Value<Int32>
[int[]]$hoge = 1, 2, 3, 4
[string[]]$fuga = "hoge", "moge", "fuga", "piyo"
New-ZipPairs -key $hoge -value $fuga
Item1 Item2
----- -----
    1 hoge 
    2 moge 
    3 fuga 
    4 piyo 
型の保持

Get-Process と Get-ChildItem の結果をペアにすると? (意味はないです)

# sample Key<System.Diagnostics.Process>, Value<System.IO.FileInfo>
New-ZipPairs -key (ps) -value (ls)

型を保持しており、Get-ChildItem の結果がすくなったので、Get-Processの結果はそこで打ち切られています。

Item1                                                 Item2             
-----                                                 -----             
System.Diagnostics.Process (Adobe CEF Helper)         Document          
System.Diagnostics.Process (AdobeIPCBroker)           GitHub            
System.Diagnostics.Process (AppleMobileDeviceService) hoge              
System.Diagnostics.Process (atieclxx)                 nuget             
System.Diagnostics.Process (atiesrxx)                 Software          
System.Diagnostics.Process (audiodg)                  toast             
System.Diagnostics.Process (CCC)                      Users             
System.Diagnostics.Process (chrome)                   valentia          
System.Diagnostics.Process (chrome)                   Visual Studio 2012

特にGet-ChildItemが厄介ですが、DirectoryInfoFileInfo が混じりえます。この場合は、それぞれのシーケンスの最初の型で、後続の型をフィルタしています。 渡す前に型合わせておくのがいいかと。

1つの場合

問題ありません。

New-ZipPairs -key "d:\hogemoge" -value "d:\fugafuga"
Item1       Item2      
-----       -----      
d:\hogemoge d:\fugafuga

まとめ

結構あちこちで使ってて便利なのでよろしければ。良く使うのは、AWSTagを作りたい時に、KeyValue を渡したりとかですね。

無駄が目立つのでもう少しうまく書けないかなとか、ほげもげ気になる点がたくさんですがほげもげ。

追記

MoveNext() 使うんじゃもんって指摘あったのでなおすもん!