見出し画像

Retro-gaming and so on

RE: Racketで何か・・017 次行ってみよう! LoLグラフユーティリティ

星田さんの記事に対するコメント。

さて、ここで選択肢が出てるな・・正規表現はサッパリなのでいきなりCametan42さんのコードをカンニングするか・・スマートではない書き方で一度挑戦してみるか・・少年漫画の主人公だったら後者を選ぶだろうからとりあえずそっちで・・長い旅になりそうだ

うん、ここは正直悩みどころなんだよなぁ・・・・・・。
例えばRacketだとstring-replaceって言う組み込み関数が提供されてるんですが・・・。

> (string-replace "living-room" #px"[^[:alnum:]]" "_")
"living_room"
>

パターン指定に正規表現を用いるので、結果regexp-replaceとあんま変わんなくなっちゃうのね。
まぁ、SRFI-13を使ってる以上シャドウイングされちゃうんだけど。
そしてSRFI-13のstring-replaceはあまり融通が利かない。このケースにはイマイチ適用出来ないのだ。

となると、ユーリティティを自作してANSI Common Lispのコードを移植する他無くなる。
一応、ここにそれらユーティリティを挙げておこう。

まずはANSI Common Lispのsubstitute-ifのScheme文字列版、string-replace-ifから。
これは実際問題、SRFI-13で提供されているstring-mapを用いればすぐ書けます。
string-mapmapと同じマッピング関数なんだけど、対象のデータ型が文字列だ、って事だけ。あとは、基本的な使い方の発想はmapと同じ。

(define (string-replace-if newitem pred? s)
 (string-map (lambda (x)
       (if (pred? x)
        newitem
        x)) s))

引数は3つ。代替文字、述語、そして対象とする文字列。
当然、述語が真を返す時、文字列の該当箇所に代替文字を差し込み、そうじゃなければそのままスルー、と。
結果、Land of Lispの提示例通りに動く関数の完成です。

> (string-replace-if #\e char-numeric? "I'm a l33t hack3r!")
"I'm a leet hacker!"
>

次はcomplementなんだけど、英単語的にはこれは「補完」と言う意味です。
そしてCommon Lisp HyperSpecに定義が載っている

Notes:
 

 (complement x) ==  #'(lambda (&rest arguments) (not (apply x arguments)))

よってこのままバカ正直に移植しちまえばイイ。

(define (complement x)
 (lambda args (not (apply x args))))

なお、ラムダ式の引数argsにカッコがないけど、これはこの部分が「可変長引数だ」と言う意味です。つまり、引数は0個以上何個でも良い、って場合にSchemeではこういう書き方をして、これがANSI Common Lispでの&rest argumentsと言う記述法に対応しています。
そしてこの「可変長引数」はリストとして纏められる。この辺はSchemeのラムダ式の基本なんで、覚えておいた方が良いでしょう。

残るはchar-alphanumeric?。ちょっと長い関数名だけど、Schemeの命名法に合わせました。
これも発想は簡単で、単にchar-alphabetic?char-numeric?の二つをorで結んどきゃいいだけ、です。

(define (char-alphanumeric? c)
 (or (char-alphabetic? c) (char-numeric? c)))

これら3つのユーティリティさえ書いておけば、Land of Lispの原版に近いコードをでっち上げる事が可能でしょう。

(define (dot-name exp)
 (string-replace-if #\_ (complement char-alphanumeric?) (format "~a" exp)))

実行例は以下の通り。

> (dot-name 'living-room)
"living_room"
> (dot-name 'foo!)
"foo_"
> (dot-name 24)
"24"

とまぁ、一応、正規表現の力を借りなくても、ユーティリティを自作すれば同じ結果を得ることは可能です。
  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最近の「RE: Racketで何か」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事