言いたいこと
早い話これが、
$list = @()
$KSAD = @("これ" , "それ", "あれ" , "どれ")
$5W1H = @("when" , "where", "who" , "what", "why", "how")
$list += New-Object PSObject -Property @{
$KSAD[0] = $null
$KSAD[1] = $null
$KSAD[2] = $null
$KSAD[3] = $null
$5W1H[0] = $null
$5W1H[1] = $null
$5W1H[2] = $null
$5W1H[3] = $null
$5W1H[4] = $null
$5W1H[5] = $null
}
こう書けたってお話を書いていこうと思います。
$list = @()
$KSAD = @("これ" , "それ", "あれ" , "どれ")
$5W1H = @("when" , "where", "who" , "what", "why", "how")
$list += New-Object PSObject | Select-Object -Property ($KSAD + $5W1H)
New-Object PSObjectでのオブジェクト作成
以前からPowershellで配列処理っぽいことをやろうと思ったとき、
New-Object PSObject -Property @{...}
を使ってオブジェクトを作成して、データを積み重ねて処理を行っていました。
New-Object PSObject
を使う際の用法は概ね上記のように -Property @{...}
を続けて記述して、プロパティ名とvalueを格納するのが一般的なのかなと、
いくつかのPowershellの記事を見て思います。
そして蓄積しようとすると、何らかの形でforループなどを用いて処理します。
こんな感じで。
$data ## 何らかの連想配列・ハッシュテーブル
$list = @()
$KSAD = @("これ" , "それ", "あれ" , "どれ")
$5W1H = @("when" , "where", "who" , "what", "why", "how")
foraech($x in $data){
$list += New-Object PSObject -Property @{
$KSAD[0] = $x.kore
~略~
$KSAD[3] = $x.dore
$5W1H[0] = $x.when
~略~
$5W1H[5] = $x.how
}
}
つまり、New-Object PSObject -Property @{}
構文にて
PSObjectを作成すると同時にプロパティとvalueを作成し、for文の数だけ繰り返す。
ということです。
しかし、当然ながら上記の構文だと@{}内でfor文やif文が使えません。
文法の幅が狭くなるということです。
例えば、連想配列を処理してると以下のような構造の連想配列があるとします。
これが | → | こうだった場合 |
---|---|---|
$data.when | → | $data.situation.when |
$data.where | → | $data.situation.where |
$data.who | → | $data.situation.who |
$data.what | → | $data.situation.what |
$data.why | → | $data.situation.why |
$data.how | → | $data.situation.how |
$5W1H = @("when" , "where", "who" , "what", "why", "how")
だとしたら、
$data.situation.whenは$data.situation[0]
、$data.situation.($5W1H[0])
のような書き方ができ、配列番号を使って指定することができます。
この配列番号を上手く使ってfor文などで繰り返しの処理を行いたいのですが、
先ほども申した通り@{}内でfor文やif文が使えません。
やろうと思うと先にNULLの状態でプロパティを作成しておき、
そのあとfor文やif文で自由に記述をすることになります。
したがって、PSObjectを作成すると同時にプロパティとvalueを作成ではなく、
PSObjectを作成すると同時にプロパティを作成し、NULLのvalueを作成する必要があります。
NULLのvalueを作成するだけなら簡単です。
New-Object PSObject -Property @{}
構文で以下のように作文するだけです。
$list += New-Object PSObject -Property @{
$KSAD[0] = $null
~略~
$KSAD[3] = $null
$5W1H[0] = $null
~略~
$5W1H[5] = $null
}
これだけです。あとは自由に各プロパティに指定の値を入れるだけです。
ですがこのNULLを入れる処理もいい感じにできないのがどうもすっきりしないのです。
New-Object PSObject | Select-Object -Property 構文の発見
何かいい方法はないかと試行錯誤しながら書き殴っていた時、ふと以下のコマンドを投入しました。
> $KSAD = @("これ" , "それ", "あれ" , "どれ")
> $5W1H = @("when" , "where", "who" , "what", "why", "how")
> $param = New-Object PSObject | Select-Object -Property ($KSAD + $5W1H)
> $param | Format-Table
これ それ あれ どれ when where who what why how
-- -- -- -- ---- ----- --- ---- --- ---
> $param | Get-Member
TypeName: Selected.System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
how NoteProperty object how=null
what NoteProperty object what=null
when NoteProperty object when=null
where NoteProperty object where=null
who NoteProperty object who=null
why NoteProperty object why=null
あれ NoteProperty object あれ=null
これ NoteProperty object これ=null
それ NoteProperty object それ=null
どれ NoteProperty object どれ=null
っ!これや!(綾鷹感)
天啓を受けたかのような爽快感です!
普段、 | Select-Object -Property
構文は指定のプロパティのみを表示させたいときに使うのですが、
指定プロパティが無い場合、NULLが入るようです。知らんかった。
New-Object PSObject -Property @{}
構文
と
New-Object PSObject | Select-Object -Property
構文
を並べてみます。
どうです?かなりすっきりしたと思いませんか?
$list += New-Object PSObject -Property @{
$KSAD[0] = $null
~略~
$KSAD[3] = $null
$5W1H[0] = $null
~略~
$5W1H[5] = $null
}
$param = New-Object PSObject | Select-Object -Property ($KSAD + $5W1H)
これがやりたかったんだよ!
考察
以下二つの構文の比較となります。
New-Object PSObject -Property @{}
構文
New-Object PSObject | Select-Object -Property
構文
このNew-Object PSObject | Select-Object -Property
構文でググってみると、
以下の記事ですでにこの構文を使っている方がいらっしゃいました。
https://qiita.com/oxalis-san/items/c33db07fcd4d10ae221f
https://mtgpowershell.blogspot.com/2011/01/psobjectnew-object.html
他にもいらっしゃるものと思いますが、それでもあまり主流ではない印象です。
というのもどこか裏技というか小技のような臭みを残している感じがします。
Select-Objectの性質上たまたまこうなっているだけなんだとしたら、
それを理由に正式なリファレンスとは言い切れないという感じなんでしょうか。
それにNew-Object PSObject -Property @{}
構文の方が、
どういった処理をしているかが分かり易いというのもあるかもしれません。
事前にNULLを入れた状態の連想配列を準備して-Propertyで指定することもできるんでしょうが、
それでもクドイ書き味になりそうです。。。
そもそもNULL使うのを控えるべきなんでしょうか?
改めて、言いたかったこと
これが、
$list = @()
$KSAD = @("これ" , "それ", "あれ" , "どれ")
$5W1H = @("when" , "where", "who" , "what", "why", "how")
$list += New-Object PSObject -Property @{
$KSAD[0] = $null
$KSAD[1] = $null
$KSAD[2] = $null
$KSAD[3] = $null
$5W1H[0] = $null
$5W1H[1] = $null
$5W1H[2] = $null
$5W1H[3] = $null
$5W1H[4] = $null
$5W1H[5] = $null
}
こう書けました。
$list = @()
$KSAD = @("これ" , "それ", "あれ" , "どれ")
$5W1H = @("when" , "where", "who" , "what", "why", "how")
$list += New-Object PSObject | Select-Object -Property ($KSAD + $5W1H)
ご拝読ありがとうございました。