Re2: Enumerable#mins_by
nowa サービス終了のお知らせ
Re: Enumerable#mins_by - チナミニ
反則?
//minsby.c #include <ruby.h> static ID id_cmp, id_each; static VALUE mins_by_i(VALUE i, VALUE *memo, int argc, VALUE *argv) { VALUE v; //ENUM_WANT_SVALUE(); if(argc == 0) { i = Qnil; } else if(argc == 1) { i = argv[0]; } else if(argc > 0) { i = rb_ary_new4(argc, argv); } v = rb_yield(i); if (memo[0] == Qundef) { memo[0] = v; rb_ary_push(memo[1], i); } else { int cmp = rb_cmpint(rb_funcall(v, id_cmp, 1, memo[0]), v, memo[0]); if (cmp < 0) { memo[0] = v; rb_ary_clear(memo[1]); rb_ary_push(memo[1], i); } else if (cmp == 0) { rb_ary_push(memo[1], i); } } return Qnil; } static VALUE enum_mins_by(VALUE obj) { VALUE memo[2]; RETURN_ENUMERATOR(obj, 0, 0); memo[0] = Qundef; memo[1] = rb_ary_new(); rb_block_call(obj, id_each, 0, 0, mins_by_i, (VALUE)memo); return memo[1]; } void Init_minsby() { rb_define_method(rb_mEnumerable, "c_mins_by", enum_mins_by, 0); id_cmp = rb_intern("<=>"); id_each = rb_intern("each"); }
Rehearsal -------------------------------------- my 0.010000 0.000000 0.010000 ( 0.005119) uj 0.000000 0.000000 0.000000 ( 0.004347) c 0.000000 0.000000 0.000000 ( 0.004221) ----------------------------- total: 0.010000sec user system total real my 0.000000 0.010000 0.010000 ( 0.004150) uj 0.010000 0.000000 0.010000 ( 0.004085) c 0.000000 0.000000 0.000000 ( 0.002646)
なお、"my"は検定中の要素に負数があるときバグりますが、"c"はバグりません。
myはselect_byのようなものを使って書きなおせればうまくいくはず。