axjack's blog

axjack is said to be an abbreviation for An eXistent JApanese Cool Klutz.

文字列処理

電話番号のような文字列からハイフンを取り除き、一文字ずつ数字にしたものを要素として持つ配列を返す関数を作ろうとしたらエラーで泣いたので整理する。泣いている暇があったらドキュメントをしっかり読もう。

基本

.inspectで型*1を調べることができる。'で囲むとCharではなくSymbolになるので要注意。

3.inspect;//Integer
"3".inspect;//String
'3'.inspect;//Symbol
\3.inspect;//Symbol
$3.inspect;//Char
[3].inspect;//Array
(3).inspect;//Interger
{3}.inspect;//Function

==演算

型が違うと==falseとなる。ここで、String

String represents an array of characters.

と説明されていることから(そして実際にも)、それぞれの要素はCharである。なので、要素を参照する時は見た目でIntegerだと思ってはならない。

3 == 3;//true: Integer vs Integer
3 == "3";//false: Integer vs String
3 == '3';//false: Integer vs Symbol
3 == \3 ;//false: Integer vs Symbol
'3' == "3";//false: Symbol vs String
'3' == \3 ;//true: Symbol vs Symbol
"3"[0] == 3;//false: Char vs Integer
"3"[0] == $3;//true: Char vs Char
"3".at(0) == $3;//true: Char vs Char
[3][0] == 3;//true: Integer vs Integer
[3].at(0) == 3;//true: Integer vs Integer
{3} == 3;//false: Function vs Integer
{3}.() == 3;//true: Integer vs Integer
{3}.(3) == 3;//true: Integer vs Integer
(3) == 3;//true: Integer vs Integer
(3).() == 3;//true: Integer vs Integer

+演算と++演算

+演算子は同一index同士で和を取るのに対して、++演算子は直和である。使えそうな小技としては、[] ++ "123";//-> [ 1, 2, 3 ]。この式で文字列から配列に変換できる。

[1,2,3] + [4,5,6];//-> [ 5, 7, 9 ]
[1,2,3] ++ [4,5,6];//-> [ 1, 2, 3, 4, 5, 6 ]

"123" + [];//-> 123 [  ]
"123" ++ [];//-> 123[  ]
[] + "123";//ERROR: Message '+' not understood.
[] ++ "123";//-> [ 1, 2, 3 ]
[1,2,3] + "";//ERROR: binary operator '+' failed.
[1,2,3] ++ "";//-> [ 1, 2, 3 ]
"" + [1,2,3];//->  [ 1, 2, 3 ]
"" ++ [1,2,3];//-> [ 1, 2, 3 ]

("foo" + "bar");//-> foo bar
"foo" ++ "bar";//-> foobar
"foo" + $b;//-> foo b
"foo" ++ $b;//-> foob
$b + "foo";//ERROR: Message '+' not understood.
$b ++ "foo";//-> bfoo

本題

やりたかったことは、「電話番号のような文字列からハイフンを取り除き、一文字ずつ数字にしたものを要素として持つ配列を返す」ことである。CharをIntegerにする、たとえば$55へと変換するには$5.digitとすれば良い。以上を踏まえてコードを書くと以下の通り。

コード

(
f = {|tel|
    var arrayfy = [] ++ _ ;
    var selecter = _.select( _ != $- );
    var collecter = _.collect( _.digit );
    (collecter <> selecter <>  arrayfy).(tel);
}
)

f.("0190-2345-6789");//-> [ 0, 1, 9, 0, 2, 3, 4, 5, 6, 7, 8, 9 ]
f.("881-902-22339-1");//-> [ 8, 8, 1, 9, 0, 2, 2, 2, 3, 3, 9, 1 ]
f.("987-8765-4321");//-> [ 9, 8, 7, 8, 7, 6, 5, 4, 3, 2, 1 ]

参考

Char | SuperCollider 3.9dev Help

String | SuperCollider 3.9dev Help

*1:正式名称がよくわからない