今日になって、Rubyの配列やハッシュにselectというメソッドがあるのを知った。
Rubyを使い始めて何年目。Enumerableの存在は知っていたものの、きちんと調べたことがなかったなぁ。
始めて使ったselectは、こんな感じ。
Info = Struct.new(:id, :name) infos = [ Info.new(1, "Alice"), Info.new(2, "Bill"), Info.new(3, "Chris"), Info.new(4, "Dan"), Info.new(5, "Elen") ] infos.select{ |item| (2 <= item.id) && (item.id <= 4) }.each { |item| puts "(#{item.id},#{item.name})" }
最近気に入っている、Haskellだとどうなるか、書いてみた。
selectAndPuts is = mapM_ print [x|x <- is, (2 <= fst x) && (fst x <= 4)] infos = [(1, "Alice"), (2, "Bill"), (3, "Chris"), (4, "Dan"), (5, "Elen")] main = selectAndPuts infos
加えて、C++でも。
#include <iostream> #include <vector> #include <functional> #include <algorithm> #include <iterator> struct Info { int id; std::string name; }; std::ostream& operator << (std::ostream& out, const Info& info) { return out << '(' << info.id << ',' << info.name << ')'; } struct cond : public std::unary_function<const Info&, bool> { bool operator () (const Info& info) { return (2 <= info.id) && (info.id <= 4); } }; void selectAndPuts(std::vector<Info> infos) { std::copy(infos.begin(), partition(infos.begin(), infos.end(), cond()), std::ostream_iterator<Info>(std::cout, "\n")); } main(int, char* []) { Info infos[] = { {1, "Alice"}, {2, "Bill"}, {3, "Chris"}, {4, "Dan"}, {5, "Elis"} }; selectAndPuts(std::vector<Info>(infos, infos + 5)); return 0; }
やっぱり、C++では不利か。
明日の自分のために捕捉。selectAndPuts関数の仮引数が参照でなくて実体になっているのは、関数内で値を破壊してしまっているので、呼び出し元の引数の値を破壊しないようにするためです。