Ruby の strip メソッド
Ruby で文字列の先頭と末尾の空白を取るメソッドは strip 。ファイルの各行に対して処理したいなら、
while line=gets puts line.strip end
Haskell で全く同じ関数あったかな?
Haskell で strip 関数の定義
自分で書くなら、まずは先頭の空白を削除する関数 lstrip を定義。次に、文字列を反転させて lstrip を適用すれば、末尾の空白を削除する rstrip 関数ができる。二つを組み合わせてできあがり。
lstrip 関数の実装。先頭要素が空白なら値を返さず、そうでなければそのまま返せばいい。
lstrip [] = [] lstrip xs'@(x:xs) | x == ' ' = lstrip xs | otherwise = xs'
rstrip 関数はリストを逆転させてから lstrip 関数を適用する。
rstrip = reverse . lstrip . reverse
二つを組み合わせる。
strip = lstrip . rstrip
日本語のファイルに対して
日本語の書かれたファイルから入力するためには、UTF8モジュールを読み込んでおく。
import qualified System.IO.UTF8 as U
標準入力にファイルを指定して、各行に stirp 関数を適用。
main = U.getContents >>= U.putStr. trim trim = unlines . map strip . lines
ここまでのコード
import qualified System.IO.UTF8 as U lstrip [] = [] lstrip xs'@(x:xs) | x == ' ' = lstrip xs | otherwise = xs' rstrip = reverse . lstrip . reverse strip = lstrip . rstrip main = U.getContents >>= U.putStr. trim trim = unlines . map strip . lines
より汎用的な関数へ
次に、半角の空白に加え、全角の空白も削除したいとする。
上記の lstrip 関数のガードに、以下のように条件を加えてもいいけれど、
x == ' ' || x == ' '
これだと条件が増えるごとに lstrip 関数を変更しなければならない。条件を関数に渡せるようにした方が後々使い回しができる。 関数が引数として渡せる言語では Strategy パターンのオンパレード。その中の言うなれば述語パターンみたいなもの。(cf. Haskell の Prelude 散策 (2) - 述語)
lstrip _ [] = [] lstrip p xs'@(x:xs) | p x = lstrip p xs | otherwise = xs'
後は、この変更に合わせて、
import qualified System.IO.UTF8 as U lstrip _ [] = [] lstrip p xs'@(x:xs) | p x = lstrip p xs | otherwise = xs' rstrip p = reverse . lstrip p . reverse strip p = lstrip p . rstrip p main = U.getContents >>= U.putStr. trim trim = unlines . map (strip isSpace) . lines isSpace x = x `elem` [' ', ' ']
takeWhile, dropWhile
Trim (programming) - Wikipedia, the free encyclopedia には、
あ~、dropWhile を使えばよかったのか。(@_@; Prelude の関数ですらスッと連想できないなぁ。 (+_+)import Data.Char (isSpace) trim :: String -> String trim = f . f where f = reverse . dropWhile isSpace
0コメント:
コメントを投稿