イテレーション比較

プログラミング言語といえばイテレータの使いやすさだと最近自分の中では思っているんですが、どれがいいですかね。その比較をやってみたいと思います。最近マイブームの言語で比較。

JAVA

Enumeration e;
while(e.hasNext()){
    //なんか処理
    e.next();
}

VBA

Dim HOGE As Collection
For Each Element In HOGE
    'なんか処理
Next Element

Ruby

hoge.each{|x|
    #なんか処理
}

以上例をあげてみました。
それにしてもJAVAのnextってなんでしょうね…、自分で次の要素に送ってあげないとイテレーションしてないじゃん。その点VBAが比較的きれいなイテレーションをとっているのは、なぜ??他がすごくくそい & 猿回しな言語なのに。で、結論いいますと、Rubyがすばらしい。ブロック付メソッド万歳です。ちなみにRubyはこんなこともできます。

Hashのキーと値でイテレーション

hash = {key => value}
hash.each{|key, value|
    #なんか処理
}

Hashを二重配列化、その上ソート(ソート条件は値で昇順)をかけて、さらにイテレーション

hash.to_a.sort{|a, b|
    b[1] <=> a[1]
}.each{|e|
    #ソートされた二重配列。キーはe[0]、値はe[1]に入っている
}

要は仕事で書かなければならないJAVAとVBAに対する腹いせです~。あぁ、Rubyが書きたい~。
某氏はJAVAを『シャバ』と読んでいました(笑)

October 26, 2003 23:59 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク

コメント

Rubyはスクリプト言語にオブジェクト指向くっつけて、さらに関数型言語的な要素も混ぜてるって言語だから、当然といえば当然かも。

純粋な関数型言語だったら、例えばML
http://caml.inria.fr/
とかだと、

List.map (fun x -> x * x) lst

とか書けば、リストlstの各要素を自乗したリストを得られます。

例に挙がっている、C系統のJava等の手続き型言語では、そもそも関数を型として扱うことは出来ないため、Collectionのような特殊なクラスを言語レベルで用意し、for-eachのような文法上の後付けをしたに過ぎないのです。(だから、本来の美しさ的には、無いほうが美しい)

Javaでの特殊な構文としては、inner-classがあります。これを使えば、オブジェクトとして関数を包み込んで、内部イテレータっぽく渡すということが可能です。
例えば、(Javaはあまり使わないので構文違うかも)

public interface Comparable {
public int compare(Object o1, Object o2);
}

public class SortList {
// ...
public int sort(Comparable cmp) {
// 比較する部分で cmp.compare(o1, o2) を呼び出す
}
}

// 使用
SortList lst;
lst.sort(new Comparable() {
public int compare(Object o1, Object o2) { // 実際に比較するコード }
});

のようにすれば、実際MyList.sortを呼び出す部分に、コードを埋め込めます。ただ、この追加仕様は、AdapterやListenerのために作られた節が強いと思われ、上記の例の場合などは、外部イテレータを使ったほうが簡潔かと思われます。

Posted by: ゆりあ : October 28, 2003 12:04 AM

なるほど。
今調べたんですが、JavaにはJava1.4でリフレクションの機能が大幅に改善されたので、Methodを足したりできるのかなぁ、そしたら特異メソッドみたいなことしてsort機能とか足したいなぁ、とか思ったんですかJavaのリフレクションは自己参照どまりのようで自己改変は不可なため、これはできないようです。

資料(なぜかLispページですが…)

Posted by: fenrir : October 28, 2003 12:37 AM

コメントする