From: daz Date: 2005-07-13T22:40:51+09:00 Subject: Re: accessing index inside map Brian Candler wrote: > > > > [1]; obj.enum(:each_with_index).inject(0) {|sum,(a,i)| sum + a*i} > > > > [2]; i=-1; obj.inject(0) {|sum, a| sum + a*(i+=1)} > > > > Can anyone shade me in on what, if any, advantage [1] has over [2]: > > -- in terms of: > > > > a) Readability > > b) Ease of use and understanding > > c) Performance > > d) Flexibility > > e) Accuracy > > f) Memory usage > > g) Anything else you care to throw in ;-) > > 1. It retains the enapsulation of "iterating with an index"; > OK. That's why I want it provided automatically inside the block. It's information known to, but not revealed by, the iterator. We're the programmers ... they're our blocks ... why can't we discover a fundamental detail like which iteration we're on ?? > you are reimplementing it in your inner block. Both examples implement an index. One as an external variable, the other as an extra block parameter provided by #each_with_index. I can't see anything I've reimplemented. We may be at cross-purposes ? > (Violation of DRY principle). Not so. There's no index, and I need one, so I have to create it. So do you. It's no more a violation of DRY than having to open a file _every_ flippin' time I want to read it. > 2. It's more general; it works with other iteration methods. Consider > Hash#each_value and Hash#each_key, or String#each_byte for example. > I've considered. I can't think of any that it wouldn't work with. Is there anything more general than that ? > require 'enumerator' > "abc".to_enum(:each_byte).collect #=> [97, 98, 99] > > Of course you could rewrite this too, but then you're reimplementing > 'collect': > > res = [] > "abc".each_byte { |x| res << x } > res OK, _that_ would be a reimplementation of 'collect' but I can't respond with an example of what I'd do because you haven't used an index. I'm talking index only, albeit within a slightly expanded topic. However, dawning is in progress, perhaps :-) # "abc".to_enum(:each_byte).collect #=> [97, 98, 99] I was about to describe the #each_byte block as a "proxy receiver" for #collect, but I think I'll wait before spreading untruths because it feels reversed (?) > > 3. If you were using the index in more than one place in the inner block, it > would become more verbose. > > i=0; obj.inject(0) { ... use i ... use i ...; i+=1 } > Absurd ;-) If your block had 30 uses of the index, my version would have 31. I'll say again - we may be mixing subjects (accessing an index versus Enumeration and it's probably just me who doesn't know the difference, yet). > > Brian. > Thanks BC, daz