Convert a string to a character arrayたまたま経験則で答えが出てたのですが、改めて勉強になりました。 さっそく見てみます。
お題目
"PowerShell"というStringを、一文字ずつのChar[]に変換しなさい。つまり、こうなるはずです。
P o w e r S h e l l
縛り
ソースにすると、これが禁止です。
- [char[]]へのキャストは禁止。
- String型が持つ.ToCharArrayメソッドは禁止。
[char[]]"PowerShell" #禁止 ("PowerShell").ToCharArray() #禁止型を調べてみましょう。
([char[]]"PowerShell").gettype().FullName ("PowerShell").ToCharArray().gettype().FullName結果は[Char[]]型ですね。
System.Char[] System.Char[]
コード例
一文字ずつ取り出す方法は、いくつか考えられます。それぞれを見ていきます。
- .GetEnumetrator()を利用
- .GetEnumetrator()を利用して順次配列にいれていく
- 配列(Array)にして一字ずつ取り出す
- 正規表現して、結果をSplitメソッドへ
- Splitメソッドを使う
.GetEnumetrator()を利用
まずはソースから。$Enumerator="PowerShell".GetEnumerator()実行してみましょう。
"------Enumerator" $Enumerator.length $Enumerator.GetType().Name "------Enumerator" $Enumerator "------Enumerator"結果です。
GetEnumerator()
では、型がCharEnumeratorになっていることが分かります。
あと、順次Enumeratorしてるので…結果が変数には…あれれ?何も出力されていません。
------Enumerator 1 1 1 1 1 1 1 1 1 1 CharEnumerator ------Enumerator ------Enumeratorこれは正常な動きです。 仮に出力したいならば変数に入れずに実行すればいいわけです。 つまりこうですね。
"PowerShell".GetEnumerator()期待通り出力します。
P o w e r S h e l l
.GetEnumetrator()を利用して順次配列にいれていく
ソースです。$EnumeratorArray=@() $EnumeratorArray += "PowerShell".GetEnumerator()実行してみましょう。
"------EnumeratorArray" $EnumeratorArray.length $EnumeratorArray.GetType().Name "------EnumeratorArray" $EnumeratorArray "------EnumeratorArray"結果です。 Charではありませんが、配列に入れているのでObjectになっていますね。 これならまぁ何とかです。 変数にも格納できています。
------EnumeratorArray 10 Object[] ------EnumeratorArray P o w e r S h e l l ------EnumeratorArray
配列(Array)にして一字ずつ取り出す
ソースです。 インデックスを直接書かない理由は、他の文字でも流用するためです。 毎度文字の度に変えるのはナンセンスです。$Array=($z="Powershell")[0..$z.Length]実行してみましょう。
"------Array" $Array.length $Array.GetType().Name "------Array" $Array "------Array"結果です。 object[]型ですがまぁ。一応上手くいきますね。
------Array 10 Object[] ------Array P o w e r s h e l l ------Array
正規表現して、結果をSplitメソッドへ
ソースです。$regexsplit=[regex]::split("PowerShell","")実行してみましょう。
"------regexsplit" $regexsplit.length $regexsplit.GetType().Name "------regexsplit" $regexsplit "------regexsplit"結果です。 突込みどころが多いしアウトです。 まず、Splitメソッドで分割すると、結果は[string]型になります。 加えて前後に余計な空白文字が1文字ずつ入って12文字になっています。
------regexsplit 12 String[] ------regexsplit P o w e r S h e l l ------regexsplit
Splitメソッドを使う
ソースです。$split='PowerShell'-split'\B'実行してみましょう。
"------split" $split.length $split.GetType().Name "------split" $split "------split"結果です。 先ほど同様の突込みでアウトです。 当然、Splitメソッドで分割すると結果は[string]型になります。 前後の余白が入らないだけマシですが。
------split 10 String[] ------split P o w e r S h e l l ------split
まとめ
@guitarrapc [System.Linq.Enumerable]::ToArray("foobar")
— だるじろうさん (@takeshik) 2013年2月5日
今回の例でいうとソースはこうです。
$linq =[System.Linq.Enumerable]::ToArray("PowerShell")実行してみます。
"------linq" $linq.length $linq.GetType().FullName "------linq" $linq "------linq"完璧な結果に流石の一言です。
------linq 10 System.Char[] ------linq P o w e r S h e l l ------linq
おまけ
lからPまで、逆さに取得したい場合は? 簡単な方法は配列のインデックスを逆にたどる方法です。 ソースはこうです。($zz="Powershell")[-1..-($zz.Length)]結果です。
l l e h s r e w o Pこれも星人はLinqでいくのが決まりということなのは最もでした。
逆転は [System.Linq.Enumerable]::Reverse('foobar') か
— だるじろうさん (@takeshik) 2013年2月5日
ソースはこうです。
[System.Linq.Enumerable]::Reverse('PowerShell')結果です。
l l e h s r e w o Pトドメの一言でした。 真理です。
LINQ は普遍
— だるじろうさん (@takeshik) 2013年2月5日