「お題:文字列を先頭から見て同じところまで除去」をjsでやってみた男
お題の説明
複数の文字列を受け取り、受け取った文字列をそれぞれ先頭から見てゆき、すべてが同じ内容であれば除去した内容の文字列を返却する関数を書いて下さい。
※関数の引数と戻り値については複数の文字列が受け渡しできれば型や方法は問いません*1。例1)hoge("abcdef", "abc123")
戻り値 => "def" と "123" ("abc" が除去される)例2)hoge("あいうえお", "あいさんさん", "あいどる")
戻り値 => "うえお", "さんさん", "どる" ("あい" が除去される)例3)hoge("12345", "67890", "12abc")
戻り値 => "12345", "67890", "12abc" (一致なしのため、そのまま返却される)
jsでやってみた
このお題の意味を、そのプログラミング言語のいいところを用いてうまくかけと解釈しましたが、無い脳をひねりだして考えてみても、うまいものが出てこないので、オーソドックスなものから派生させていく作戦をとることにしました。
尚、複数文字列の渡し方は何でもいいという条件なので、文字列の配列を引数とする関数になっています。
function hoge(array) { var i, j, l; for (i = 1, l = array[0].length; i < array.length; ++i, l = j) for (j = 0, l = Math.min(array[i].length, l); j < l && array[0][j] === array[i][j]; ++j); for (i = 0; i < array.length; ++i) array[i] = array[i].substr(l); return array; }
forをどうするかですがmapと再帰しか思いつきませんで、以下のようになりました。
function hoge(array) { try { return arguments.callee(array.map(function (s) { if (array[0][0] !== s[0]) throw "不一致"; return s.substr(1); })); } catch (e) { return array; } }
関数は先頭の1文字しか調べません。完全一致で1文字削ったのを関数の引数として渡しています。不一致のときは例外を投げてmapから抜け出し引数の配列をそのまま返します。
eを調べないところがいい加減です。
function hoge(array) { var flag, a = array.map(function (s) { if (array[0][0] !== s[0]) flag = 1; return s.substr(1); }); return flag ? array : arguments.callee(a); }
これは例外を使いませんがmapから途中で抜け出せません。
hoge("asdf", "fdsa")みたいに使うには、array = Array.apply(0, arguments)とか書けばできます。
下二つの恐ろしいところは100文字一致で再帰の深さが100になるところです。