komorebikoboshiのブログ

プログラミング記事(趣味レベル)が多め。

F#の文字列操作関数を調べてみた

F#の文字列操作関数(Microsoft.FSharp.Core.Stringモジュール)を調べてみた。

関数

length

文字列の長さを返す。

String.length "あいうえお"
(* => 5 *)
map

文字それぞれに関数を適用した新しい文字列を作る。

String.map (fun x -> System.Char.ToUpper(x)) "hello,world"
(* => "HELLO,WORLD" *)
collect

mapと似ているけどこちらは「一文字→複数文字」の変換が可能。

String.collect (fun x -> "[" + x.ToString() + "]") "abcde"
(* => "[a][b][c][d][e]" *)
concat

文字列のシーケンス(リストとか)を区切り文字を入れて連結する。他のプログラミング言語だとjoinとかと呼ばれることが多い。

String.concat ", " ["I";"my";"me";"mine"]
(* => "I, my, me, mine" *)
exists

述語関数(true/falseを返す関数)を満たす文字が一つでもあればtrue、なければfalse。

String.exists (fun x -> x = 'a') "abcde"
(* => true *)

String.exists (fun x -> x = 'a') "あいうえお"
(* => false *)
forall

すべての文字が述語関数を満たせばtrue。

String.forall System.Char.IsDigit "12345"
(* => true *)

String.forall System.Char.IsDigit "12x45"
(* => false *)

(System.Char.IsDigit……文字が10進数の数字だった場合にtrue)

init

for文使って一文字ずつ作る感じ?

String.init 10 (fun x -> x.ToString())
(* => "0123456789" *)

エラー処理とか端折って書くとこんな感じ

let my_init count func =
    let mutable res = ""

    for i = 0 to count - 1 do
        res <- res + func i

    res
iter

まんまfor文。

String.iter (printfn "%c") "abcde" 
(* =>

a
b
c
d
e

*)

これと一緒(エラー処理とかしてないけど)

for c in "abcde" do
    printfn "%c" c
iteri

iterの文字とインデックスを渡すバージョン。

String.iteri (fun i c -> printfn "(%d, %c)" i c) "abcde"
(* =>

(0, a)
(1, b)
(2, c)
(3, d)
(4, e)

*)
mapi

mapの関数に文字とインデックスを渡すバージョン。いつ使うんだ?

String.mapi (fun i c -> if i % 2 = 0 then System.Char.ToUpper(c) else c) "helloworld"
(* => "HeLlOwOrLd" *)
(* 奇数番目の文字(インデックスが偶数の文字)を大文字に *)
replicate

文字列を繰り返す。

String.replicate 3 "おにいちゃん"
(* => "おにいちゃんおにいちゃんおにいちゃん" *)
(* 本当は幼馴染の方が好き *)

その他

.NET Frameworkのメソッドは普通に使える。

".exe;.com;.bat".Split(';')
(* => [|".exe"; ".com"; ".bat"|] *)

"aabbcc".Replace('b','f')
(* => "aaffcc" *)

感想

文字列操作というよりは文字のcollectionを操作する感じ。普通の文字列処理は.NET Frameworkのメソッドでやる、ということなのかな?

以下余談

F#自体には普通の意味での文字列操作関数(replaceとか)がなくて、そういう操作は文字列のメソッドでやる。そのことから、F#はひとつの言語というよりは.NET Frameworkのライブラリをあつかう文法のような感じを受ける。そしてそれはC#VBも同じ。*1でまあようするに、F#(もしくはC#VB)もライブラリにべっとり甘えて書けると思えば、そこまで身構える必要もないのかなあ、と。
(追記)F#のシンタックスハイライトってどうやるのだろう?

*1:言語自体にそういう関数があるわけではない