From: nobuyoshi nakada Date: 2005-07-11T14:29:24+09:00 Subject: Re: accessing index inside map Hi, At Mon, 11 Jul 2005 14:09:41 +0900, Ryan Leavengood wrote in [ruby-talk:147729]: > > What about Enumerator#with_index? > > > > [1,2,3,4,5,6].map.with_index {|x,i|[2,5].include?(i) ? x : x*2} > > I like that, personally. In fact each_with_index could become > each.with_index (though we obviously need the old one for backwards > compatibility.) Indeed. $ ./ruby -renumerator -e 'p (1..6).to_enum.with_index{|x,i|p [x,i]}' [1, 0] [2, 1] [3, 2] [4, 3] [5, 4] [6, 5] 1..6 A patch based on the current implementation. Index: ext/enumerator/enumerator.c =================================================================== RCS file: /cvs/ruby/src/ruby/ext/enumerator/enumerator.c,v retrieving revision 1.3.2.2 diff -U2 -p -r1.3.2.2 enumerator.c --- ext/enumerator/enumerator.c 4 Nov 2004 01:20:50 -0000 1.3.2.2 +++ ext/enumerator/enumerator.c 11 Jul 2005 05:25:15 -0000 @@ -162,4 +162,27 @@ enumerator_each(obj) } +static VALUE +enumerator_with_index_i(val, memo) + VALUE val, *memo; +{ + val = rb_yield_values(2, val, INT2FIX(*memo)); + ++*memo; + return val; +} + +static VALUE +enumerator_with_index(obj) + VALUE obj; +{ + VALUE memo = 0; + + obj = (VALUE)rb_node_newnode(NODE_MEMO, + rb_ivar_get(obj, id_enum_obj), + rb_to_id(rb_ivar_get(obj, id_enum_method)), + rb_ivar_get(obj, id_enum_args)); + return rb_iterate((VALUE (*)_((VALUE)))enumerator_iter, obj, + enumerator_with_index_i, (VALUE)&memo); +} + void Init_enumerator() @@ -183,4 +206,5 @@ Init_enumerator() rb_define_method(rb_cEnumerator, "initialize", enumerator_initialize, -1); rb_define_method(rb_cEnumerator, "each", enumerator_each, 0); + rb_define_method(rb_cEnumerator, "with_index", enumerator_with_index, 0); sym_each = ID2SYM(rb_intern("each")); -- Nobu Nakada