PowerShellでStringをChar[]に変換する2013-02-05PowerShellでStringをChar[]に変換するPowerShell表題の事案には、シェル芸で試みている時に巡り会っていたのです。いつもの問題出題サイトで表題の試みが行われていたようです。arrayたまたま経験則で答えが出てたのですが、改めて勉強になりました。お題目"PowerShell"というStringを、一文字ずつのChar[]に変換しなさい。PowerShell縛り[char[]]へのキャストは禁止。String型が持つ.ToCharArrayメソッドは禁止。ソースにすると、これが禁止です。型を調べてみましょう。([char[]]"PowerShell").gettype().FullName("PowerShell").ToCharArray().gettype().FullName結果は[Char[]]型ですね。一文字ずつ取り出す方法は、いくつか考えられます。.GetEnumetrator()を利用.GetEnumetrator()を利用して順次配列にいれていく配列(Array)にして一字ずつ取り出す正規表現して、結果をSplitメソッドへSplitメソッドを使うそれぞれを見ていきます。.GetEnumetrator()を利用まずはソースから。$Enumerator="PowerShell".GetEnumerator()実行してみましょう。"------Enumerator"$Enumerator.length$Enumerator.GetType().Name"------Enumerator"$Enumerator"------Enumerator"結果です。GetEnumerator()では、型がCharEnumeratorになっていることが分かります。あと、順次Enumeratorしてるので...結果が変数には...あれれ?何も出力されていません。------Enumerator1111111111CharEnumerator------Enumerator------Enumeratorこれは正常な動きです。仮に出力したいならば変数に入れずに実行すればいいわけです。"PowerShell".GetEnumerator()期待通り出力します。PowerShell.GetEnumetrator()を利用して順次配列にいれていくソースです。"PowerShell".GetEnumerator()実行してみましょう。"------EnumeratorArray"$EnumeratorArray.length$EnumeratorArray.GetType().Name"------EnumeratorArray"$EnumeratorArray"------EnumeratorArray"結果です。Charではありませんが、配列に入れているのでObjectになっていますね。これならまぁ何とかです。変数にも格納できています。------EnumeratorArray10Object[]------EnumeratorArrayPowerShell------EnumeratorArray配列(Array)にして一字ずつ取り出すソースです。インデックスを直接書かない理由は、他の文字でも流用するためです。毎度文字の度に変えるのはナンセンスです。$Array=($z="Powershell")[0..$z.Length]実行してみましょう。"------Array"$Array.length$Array.GetType().Name"------Array"$Array"------Array"結果です。object[]型ですがまぁ。一応上手くいきますね。------Array10Object[]------ArrayPowershell------Array正規表現して、結果をSplitメソッドへソースです。$regexsplit=[regex]::split("PowerShell","")実行してみましょう。"------regexsplit"$regexsplit.length$regexsplit.GetType().Name"------regexsplit"$regexsplit"------regexsplit"結果です。突込みどころが多いしアウトです。Splitメソッドで分割すると、結果は[string]型になります。加えて前後に余計な空白文字が1文字ずつ入って12文字になっています。------regexsplit12String[]------regexsplitPowerShell------regexsplitSplitメソッドを使うソースです。$split='PowerShell'-split'\B'実行してみましょう。"------split"$split.length$split.GetType().Name"------split"$split"------split"結果です。先ほど同様の突込みでアウトです。Splitメソッドで分割すると結果は[string]型になります。前後の余白が入らないだけマシですが。------split10String[]------splitPowerShell------splitまとめ以上から、[char]型で取得するには、明示的な型変換が必要です。」でいれるか「$x[インデックス指定]」で入れることで[object]型は取得できます。Splitは[string]になりますので注意です。ありがたいことに、公開して10分で、某星人から指摘がありました。今回の例でいうとソースはこうです。=[System.Linq.Enumerable]::ToArray("PowerShell")実行してみます。"------linq"$linq.length$linq.GetType().FullName"------linq"$linq"------linq"完璧な結果に流石の一言です。簡単な方法は配列のインデックスを逆にたどる方法です。($zz="Powershell")[-1..-($zz.Length)]結果です。llehsrewoPこれも星人はLinqでいくのが決まりということなのは最もでした。2013年2月5日ソースはこうです。[System.Linq.Enumerable]::Reverse('PowerShell')結果です。llehsrewoPトドメの一言でした。