inject、畳み込み2006年10月16日 22時06分

IT戦記 - Perl で再帰呼出し時のスタック間データ共有を読んだ時点では気づきもせず、Kazuho@Cybozu Labs: JavaScript で Generic Programming にいたってようやく思い当たったのだが、Ruby の Enumerable#injectPython の reduce というのはこういうときに使うものなのかもしれない。

// requires Prototype.js
function count_tags(node) {
  return $A(node.childNodes).inject({}, function (tag, kid) {
    if (kid.nodeType != 1) return tag;
    tag[kid.nodeName] = (tag[kid.nodeName] || 0) + 1;
    return $A(kid.childNodes).inject(tag, arguments.callee);
  });
}

さて、このような畳み込み関数の名前は inject、reduce、foldl など言語によりばらばらで、逆に言えばこれぞというべき名前がないようで、Ruby のフォーラムでも inject というメソッド名はわかりづらいというトピックがあった。代替案として出ていたのは combine、each_with_state、accumulate など。個人的には、reduce は何を「減らす」のよくわからず、foldl は JavaScript の命名習慣から外れているようで、「リストの要素間に二項演算を『注入』する」という解釈も含めて inject が好みなのだが、もし JavaScript に採用されることがあっても名前は reduce になるんだろうなという気がする。

ところで、畳み込み関数について検索していたら、foldl.com というサイトを見つけた。JavaScript を有効にする必要があるがなかなか面白いサイトだ。ここで、ふと思いついて foldr.com とアドレスバーに入力してみたら……。いやはや、盛大に笑わせてもらった。

コメント

_ mal ― 2006年12月07日 22時24分

はじまっちゃいましたね。
https://bugzilla.mozilla.org/show_bug.cgi?id=363040
やっぱ reduce (-_-)

確か inject は SmallTalk 由来、reduce は Common Lisp あたりでしょうか。

_ nanto_vi ― 2006年12月08日 01時13分

始まりましたね。
"Python's moribund reduce"という表現が気にかかります。reduceが実際には使われていないということでしょうか?
個人的には初期値の指定はぜひほしいところです。

_ mal ― 2007年04月10日 23時22分

知らないうちに入ってました。一月の頭。
http://bonsai.mozilla.org/cvslog.cgi?file=mozilla/js/src/jsarray.c&rev=HEAD&mark=3.105
こんなコメントじゃわからないよー!

[3,4,5].reduce(function(a,b){return a + b}, 6) // 18
[3,4,5].reduceRight(function(a,b){return a - b}, 20) // 8
動いてます。

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※投稿には管理者が設定した質問に答える必要があります。

名前:
メールアドレス:
URL:
次の質問に答えてください:
「ハイパーテキストマークアップ言語」をアルファベット4文字でいうと?

コメント:

トラックバック

このエントリのトラックバックURL: http://nanto.asablo.jp/blog/2006/10/16/563410/tb