高階関数で書き直し
昨日の JavaScript で Listモナド [id:gakuzo:20090401:1238599220] ですが、サンプルのために expandCharClass と expandAltWords をベタっと書きましたが、本来ならもう少しすっきり書きたいですね。
先に String.prototype.toArray を定義しておきます。prototype.js を使用している場合は必要ありません。
// prototype.js では実装されているので prototype.js を使用している場合は必要ありません。 if (!String.prototype.toArray) { String.prototype.toArray = function() { var result = []; for (var i = 0, n = this.length; i < n; i++) { result[i] = this.charAt(i); // Array.prototype.push を使用しないのは MacIE 対策 } return result; } }
そうすると expandCharClass や expandAltWords は次の様に書けます。
function expandCharClass(str) { return expandCommon(str, /(.*)\[(.*?)\](.*)/, String.prototype.toArray, [], arguments.callee); } function expandAltWords(str) { return expandCommon(str, /(.*)\{(.*?)\}(.*)/, String.prototype.split, [","], arguments.callee); } function expandCommon(str, regexp, matchedHandler, handlerArguments, ref) { if (!str.match(regexp)) return [str]; var matched = matchedHandler.apply(RegExp.$2, handlerArguments); return jQuery.map(matched, function(e) {return RegExp.$1 + e + RegExp.$3;}).bind(ref); // jQuery版 // return matched.map(function(e) {return RegExp.$1 + e + RegExp.$3;}).bind(ref); // prototype.js版 }
高階関数さまさまですね。
因みに昨日の記事で再帰してたり、今回 bind 使ったりしているのは、"img[012][abc].png" の様に複数回パターンが存在した時の為です。
2009-04-02 21:41 編集
jQuery か prototype.js があること前提だったので map 使って expandCommon を簡略化。
2009-04-04 11:23 編集
map 使って書き直したので、Array.prototype.push が 1度しか使われなくなり、このエントリの本題とも関係ないので Array.prototype.push の実装を削除。