[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: accessing index inside map

Peña, Botp

7/8/2005 9:11:00 AM

nobuyoshi nakada [mailto:nobuyoshi.nakada@ge.com] wrote:

#> i'd like to double the element values except those loc on
#the 2nd and 5th
#> indices eg.
#
#$ ruby -renumerator -e 'p
#(1..6).enum_for(:each_with_index).map{|x,i|[2,5].include?(i) ?
#x : x*2}'
#[2, 4, 3, 8, 10, 6]

Hi Nobu,

Wow, cool. But my brain is very tiny compared to other rubyist brains.

i was hoping for something straight like,

>[1,2,3,4,5,6].map{|x,i|[2,5].include?(i) ? x : x*2}
=>[2, 4, 3, 8, 10, 6]

Maybe you can hack one for dumb rubyists like me.

thanks and kind regards -botp

#
#--
#Nobu Nakada
#


25 Answers

Robert Klemme

7/8/2005 10:17:00 AM

0

Peña, Botp wrote:
> nobuyoshi nakada [mailto:nobuyoshi.nakada@ge.com] wrote:
>
> #> i'd like to double the element values except those loc on
> #the 2nd and 5th
> #> indices eg.
> #
> #$ ruby -renumerator -e 'p
> #(1..6).enum_for(:each_with_index).map{|x,i|[2,5].include?(i) ?
> #x : x*2}'
> #[2, 4, 3, 8, 10, 6]
>
> Hi Nobu,
>
> Wow, cool. But my brain is very tiny compared to other rubyist brains.
>
> i was hoping for something straight like,
>
>> [1,2,3,4,5,6].map{|x,i|[2,5].include?(i) ? x : x*2}
> =>[2, 4, 3, 8, 10, 6]
>
> Maybe you can hack one for dumb rubyists like me.

Err, are you kidding? Enumerator isn't really that difficult - and you
don't need to modify Hash or other classes. It's a simple wrapper
delegating each to each_with_index. That simple.

Regards

robert

dblack

7/8/2005 10:41:00 AM

0

dblack

7/8/2005 10:45:00 AM

0

Michael Campbell

7/8/2005 12:56:00 PM

0

On 7/8/05, David A. Black <dblack@wobblini.net> wrote:
> Hi --

> I'd still like to see #man_with_index added to Enumerable.

"index" implies an ordering, which maps by definition don't have.
Shouldn't that be something along the lines of "#map_with_key"?

But point taken; it seems a natural thing, regardless of actual name,
to be in Enumerable.


dblack

7/8/2005 1:25:00 PM

0

Robert Klemme

7/8/2005 1:31:00 PM

0

Michael Campbell wrote:
> On 7/8/05, David A. Black <dblack@wobblini.net> wrote:
>> Hi --
>
>> I'd still like to see #man_with_index added to Enumerable.
>
> "index" implies an ordering, which maps by definition don't have.
> Shouldn't that be something along the lines of "#map_with_key"?
>
> But point taken; it seems a natural thing, regardless of actual name,
> to be in Enumerable.

Key is ambiguous with Hashes... Apart from that: I'm not really sure
whether I like that idea. The basic property of an Enumerable is that it
can be enumerated with each. There are no guarantees about order etc.
each_with_index is really only there to simplify counting. If you want
map_with_index then you'd probably have to provide inject_with_index,
find_with_index etc. Personally I think that map_with_index is rarely
used to justify adding this to the std lib. Just my 0.02 EUR of course.

Btw, another variant for mapping with index:

enum.inject([]) {|ar,el| ar << ([0,3].include?(ar.size) ? el : el*2) }

Kind regards

robert

dblack

7/8/2005 1:55:00 PM

0

Yukihiro Matsumoto

7/8/2005 2:02:00 PM

0

Hi,

In message "Re: accessing index inside map"
on Fri, 8 Jul 2005 19:20:48 +0900, "Robert Klemme" <bob.news@gmx.net> writes:

|> #$ ruby -renumerator -e 'p
|> #(1..6).enum_for(:each_with_index).map{|x,i|[2,5].include?(i) ?
|> #
|> #[2, 4, 3, 8, 10, 6]
|>
|> Hi Nobu,
|>
|> Wow, cool. But my brain is very tiny compared to other rubyist brains.
|>
|> i was hoping for something straight like,
|>
|>> [1,2,3,4,5,6].map{|x,i|[2,5].include?(i) ? x : x*2}
|> =>[2, 4, 3, 8, 10, 6]
|>
|> Maybe you can hack one for dumb rubyists like me.
|
|Err, are you kidding? Enumerator isn't really that difficult - and you
|don't need to modify Hash or other classes. It's a simple wrapper
|delegating each to each_with_index. That simple.

We have vague plan to make enumerating method to return Enumerator
when no block is given in the future, so that

require 'enumerator'
(1..6).enum_for(:each_with_index).map{|x,i|[2,5].include?(i) ? x : x*2}

would be

(1..6).each_with_index.map{|x,i|[2,5].include?(i) ? x : x*2}

then. It's much simpler isn't it?

matz.


Robert Klemme

7/8/2005 2:17:00 PM

0

David A. Black wrote:
> Hi --
>
> On Fri, 8 Jul 2005, Robert Klemme wrote:
>
>> Michael Campbell wrote:
>>> On 7/8/05, David A. Black <dblack@wobblini.net> wrote:
>>>> Hi --
>>>
>>>> I'd still like to see #man_with_index added to Enumerable.
>>>
>>> "index" implies an ordering, which maps by definition don't have.
>>> Shouldn't that be something along the lines of "#map_with_key"?
>>>
>>> But point taken; it seems a natural thing, regardless of actual
>>> name, to be in Enumerable.
>>
>> Key is ambiguous with Hashes... Apart from that: I'm not really sure
>> whether I like that idea. The basic property of an Enumerable is
>> that it can be enumerated with each. There are no guarantees about
>> order etc. each_with_index is really only there to simplify
>> counting. If you want map_with_index then you'd probably have to
>> provide inject_with_index, find_with_index etc. Personally I think
>> that map_with_index is rarely used to justify adding this to the std
>> lib. Just my 0.02 EUR of course.
>
> I'm not a stickler for symmetry (my slogan for Ruby is "The triumph of
> balance over symmetry" :-) but it does seem a little arbitrary to have
> it recognized that #each_with_index is important for arrays, and #map
> is important, but #map_with_index isn't. (I emphasize "arrays"; I've
> never seen a case where it was needed or useful for hashes.) I don't
> think there's any implication that you'd have to have *_with_index.
> Nor any demand: I've never seen anyone implement #find_with_index
> (what exactly would it do? :-) but I've seen many of
> Array#each_with_index.

What about removing this completely from Enumerable and doing it like
this:

class Indexer
include Enumerable

def initialize(obj)
# @meth = meth
@obj = obj
end

def each
i = 0
@obj.each {|*a| yield *(a << i); i+=1}
self
end
end

module Enumerable
def indexer() Indexer.new(self) end
end

>> aa=[10,20,30]
=> [10, 20, 30]
>> aa.indexer.each {|a,i| printf "%4d. %s\n", i, a}
0. 10
1. 20
2. 30
=> #<Indexer:0x1017edc8 @obj=[10, 20, 30]>
>> aa.indexer.map {|a,i| a*i}
=> [0, 20, 60]
>> aa.indexer.inject([]) {|ar,(a,i)| ar << sprintf( "%4d. %s", i, a)}
=> [" 0. 10", " 1. 20", " 2. 30"]

>> hh={10=>:a, 20=>:b, 30=>:c}
=> {30=>:c, 20=>:b, 10=>:a}
>> hh.indexer.each {|(k,v),i| printf "%4d. %s => %s\n", i, k, v}
0. 30 => c
1. 20 => b
2. 10 => a
=> #<Indexer:0x101a1940 @obj={30=>:c, 20=>:b, 10=>:a}>
>> hh.indexer.map {|(k,v),i| "#{k}=>#{v}" * i}
=> ["", "20=>b", "10=>a10=>a"]
>> hh.indexer.inject([]) {|ar,((k,v),i)| ar << sprintf( "%4d. %s => %s",
i, k, v)}
=> [" 0. 30 => c", " 1. 20 => b", " 2. 10 => a"]

Admittedly the last example looks a bit awkward - but #inject is not easy
anyway and it stays consistend with the others.

Kind regards

robert

William Morgan

7/8/2005 2:42:00 PM

0

Excerpts from Michael Campbell's mail of 8 Jul 2005 (EDT):
> On 7/8/05, David A. Black <dblack@wobblini.net> wrote:
> > I'd still like to see #man_with_index added to Enumerable.
>
> "index" implies an ordering, which maps by definition don't have.
> Shouldn't that be something along the lines of "#map_with_key"?

"Map" here means "collect", not "Hash".

--
William <wmorgan-ruby-talk@masanjin.net>