文字列を先頭から見て同じところまで除去 (2)

前回の記事で書いたソースをいじってみましょう。

下記2点が気になりました。

  • リストに1つしか文字列がないときに期待通りの動きをしない。

これは、lists:all(Fun, []) が true を返すためですね。

  • 1文字辿るのに2回もループを回している。

lists:all/2 と、lists:map です。これを同時にできる方法があればいいのですが、標準で使えそうなものを見つけることができなかったので自作しました(ahya:split)。

-module(ahya).
-compile(export_all).

split(L) ->
    split(L, [], []).
split([],  _,  Tails) ->
    lists:reverse(Tails);

split([H|TL], Head, Tails) ->
    [H1|T1] = H,
    case Head of
	[] ->
	    split(TL, H1, [T1|Tails]);
	H1 ->
	    split(TL, Head, [T1|Tails]);
	_ ->
	    failed
    end.

ahya2([[]|L]) ->
    [[]|L];
ahya2([H|[]]) ->
    [H];
ahya2(L) ->
    case split(L) of
	failed ->
	    L;
	Tails ->
	    ahya2(Tails)
    end.

前回試した範囲では同じ結果を返しているようです。lists:reverse/1呼んでるじゃないか、という厳しい声が上がりそうですし、コードを読んだときのわかりやすさがだいぶ損われてしまったように思いますね。