Ruby equivalent to Python's map()?

Hi…

I’m a Python programmer and I’m trying Ruby now. I love Smalltalk and
Ruby’s “OO-ness” and likeness to Smalltalk gives me warm feelings. I’m
really excited about Ruby, enough to consider switching to it from
Python.

However, I was messing around yesterday with Ruby and looked
everywhere for some functionality close to the map() function on
python, but couldn’t find it anywhere. For those that don’t know the
function, here’s a raw example:

a = [1,2,3]
b = [4,5,6]
map(None, a, b) --> [[1,4],[2,5],[3,6]]

The first parameter above can be any function taking 2 parameters and
returning a tuple. A ruby equivalent would be something of the form:

map(a,b) {|i,j| i,j}

I thought about taking the arrays on the argument, generate iterators
for each of them, and then calling the iterators, splicing the result
into a resulting array, but could some real Ruby programmer post
some solution here? :slight_smile:

Best regards,

Roberto “Wolfox” Amorim
Software Developer - Brazil

I thought about taking the arrays on the argument, generate iterators
for each of them, and then calling the iterators, splicing the result
into a resulting array, but could some *real* Ruby programmer post
some solution here? :slight_smile:

Look in RAA

  http://www.ruby-lang.org/en/raa.html

In the category "Library / Datastructure" you'll probably find what you
want (for example "Synchronized Multi Iterator")

Guy Decoux

What class this “map function” should be method of?

I’m not sure this is the most elegant way…

a = [1,2,3]
b = [4,5,6]
c = [] # the result

a.each_with_index{|e,i| c << [e,b[i]] }

‘Enumerable#collect’ is the closest method to Python’s function ‘map’. There
is synonim ‘Enumerable#map’ :wink:

c = b.collect{|e| -e}

In article 82c04a2.0211140526.115c9413@posting.google.com,

···

Roberto Amorim wolfoxbr@hotmail.com wrote:

Hi…

I’m a Python programmer and I’m trying Ruby now. I love Smalltalk and
Ruby’s “OO-ness” and likeness to Smalltalk gives me warm feelings. I’m
really excited about Ruby, enough to consider switching to it from
Python.

However, I was messing around yesterday with Ruby and looked
everywhere for some functionality close to the map() function on
python, but couldn’t find it anywhere. For those that don’t know the
function, here’s a raw example:

a = [1,2,3]
b = [4,5,6]
map(None, a, b) → [[1,4],[2,5],[3,6]]

Hmmm… this seems to be what the proposed ‘zip’ method on Array would do.
It’s not included yet, but apparently has been approved.

I’m not sure that ‘zip’ is the best name, though…

Phil

Roberto Amorim wrote:

Hi…


However, I was messing around yesterday with Ruby and looked
everywhere for some functionality close to the map() function on
python, but couldn’t find it anywhere. For those that don’t know the
function, here’s a raw example:

a = [1,2,3]
b = [4,5,6]
map(None, a, b) → [[1,4],[2,5],[3,6]]

The better way to do this in Python is with “zip”. map() is better for
applying a function to one or more lists. If zip had been invented when
map was invented, map probably wouldn’t even have this map(None) feature.

Paul Prescod

Just a quick hack, but you can use this:

class Array
def zip(*arrays)
zipped =
all = [self, *arrays]
max_length = all.collect {|a| a.length}.max

0.upto(max_length-1) do |i|
  zipped << all.collect {|a| a[i]}
end
return zipped

end

def each2(*arrays, &block)
zip(*arrays).each(&block)
end

def collect2(*arrays, &block)
zip(*arrays).collect(&block)
end
end

a = [1, 2, 3]
b = [4, 5, 6]
c = [7, 8, 9]

a.each2(b) {|i, j| …}
a.each2(b, c) {|i, j, k| …}

collect2 just behaves as you’d expect it to.

Massimiliano

···

On Thu, Nov 14, 2002 at 10:39:44PM +0900, Roberto Amorim wrote:

The first parameter above can be any function taking 2 parameters and
returning a tuple. A ruby equivalent would be something of the form:

map(a,b) {|i,j| i,j}

Phil Tomson wrote:

In article 82c04a2.0211140526.115c9413@posting.google.com,

Hi…

I’m a Python programmer and I’m trying Ruby now. I love Smalltalk and
Ruby’s “OO-ness” and likeness to Smalltalk gives me warm feelings. I’m
really excited about Ruby, enough to consider switching to it from
Python.

However, I was messing around yesterday with Ruby and looked
everywhere for some functionality close to the map() function on
python, but couldn’t find it anywhere. For those that don’t know the
function, here’s a raw example:

a = [1,2,3]
b = [4,5,6]
map(None, a, b) → [[1,4],[2,5],[3,6]]

Hmmm… this seems to be what the proposed ‘zip’ method on Array would do.
It’s not included yet, but apparently has been approved.

I’m not sure that ‘zip’ is the best name, though…

Phil

Third party modules ok?

require “hashslice”
c[*a] = *b
c.to_a → [[1, 4], [2, 5], [3, 6]]

Regards,

Dan

···

Roberto Amorim wolfoxbr@hotmail.com wrote:

Hi–

···

On Fri, 15 Nov 2002, Phil Tomson wrote:

a = [1,2,3]
b = [4,5,6]
map(None, a, b) → [[1,4],[2,5],[3,6]]

Hmmm… this seems to be what the proposed ‘zip’ method on Array would do.
It’s not included yet, but apparently has been approved.

I’m not sure that ‘zip’ is the best name, though…

I think zip is the traditional name for this function in functional
languages.

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

[1,2,3,4].map { |x| x*2 }

-> [2, 4, 6, 8]

That’s probably what you want. Enumerable#map is a synonym for collect
by the way.

VInce

···

Vincent Foley-Bourgon
Email: vinfoley@iquebec.com
Homepage: http://darkhost.mine.nu:81

Hi –

######################################################

module Enumerable
def collectm(*args,&proc)
result =
each_with_index{|e,i| res << yield(e,*args.collect{|f| f[i]})}
return result
end
end

Two questions, and some further hacking:

  1. Why “collectm” as the name?
  2. Are you sure you want the block to be mandatory? (See my Array#braid
    and a couple of other posts for versions that have a non-block
    option.)

Further hacking:

You could dispense with your temporary variable if you wanted:

def collectm(*args)
(0…size).map {|i| yield([self,*args].map {|a| a[i]})}
end

This is also a good example of why I wish we had map_with_indices.
Hey, wait a minute, we do:

module Enumerable
def map_with_indices
(0…size).each {|i| yield(at(i),i)}
end
end

Now your method could be:

module Enumerable
def collectm(*args)
map_with_indices {|e,i| yield(e,*args.map {|a| a[i]})}
end
end

which doesn’t really change much but I think is cool :slight_smile:

David

···

On Fri, 15 Nov 2002, Aleksei Guzev wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

In article Pine.LNX.4.44.0211141510200.25273-100000@candle.superlink.net,

···

dblack@candle.superlink.net wrote:

Hi–

On Fri, 15 Nov 2002, Phil Tomson wrote:

a = [1,2,3]
b = [4,5,6]
map(None, a, b) → [[1,4],[2,5],[3,6]]

Hmmm… this seems to be what the proposed ‘zip’ method on Array would do.
It’s not included yet, but apparently has been approved.

I’m not sure that ‘zip’ is the best name, though…

I think zip is the traditional name for this function in functional
languages.

Perhaps, but when I see ‘zip’ I’m thinking it has something to do with
compression.

Phil

I think zip is the traditional name for this function in functional
languages.

Could it have been related to the functionality of a zipper ?

^^^^

Is that `map’?

Massimiliano

···

On Sat, Nov 16, 2002 at 11:01:19PM +0900, dblack@candle.superlink.net wrote:

This is also a good example of why I wish we had map_with_indices.
Hey, wait a minute, we do:

module Enumerable
def map_with_indices
(0…size).each {|i| yield(at(i),i)}

Ok.

All those debates (nicluding my post) show great Ruby’s abilities to
implement such things easyly and efficiently.

Hi –

···

On Fri, 15 Nov 2002, Shashank Date wrote:

I think zip is the traditional name for this function in functional
languages.

Could it have been related to the functionality of a zipper ?

I’ve always assumed so. Which makes one wonder about an n-dimensional
one :slight_smile:

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

What do you all think of the term “collate”?

From webster.com,
b : to assemble in proper order; especially : to assemble (as printed
sheets) in order for binding

Rudi

“Shashank Date” sdate@kc.rr.com wrote in message news:xOZA9.20687$jj5.501618@twister.rdc-kc.rr.com

···

I think zip is the traditional name for this function in functional
languages.

Could it have been related to the functionality of a zipper ?

Hi –

···

On Sun, 17 Nov 2002, Massimiliano Mirra wrote:

On Sat, Nov 16, 2002 at 11:01:19PM +0900, dblack@candle.superlink.net wrote:

This is also a good example of why I wish we had map_with_indices.
Hey, wait a minute, we do:

module Enumerable
def map_with_indices
(0…size).each {|i| yield(at(i),i)}
^^^^

Is that `map’?

Yes. Serves me right for hacking at it before posting, rather than
posting the one that had been sitting in my archive for two years :slight_smile:

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav