From: sabbyxtabby@... (Sabby and Tabby) Date: 2003-08-30T09:00:11+09:00 Subject: Re: multiply all array with array Martin DeMello wrote: > ibotty wrote: > > > >> Not quite, but for parallel traversing made easier > >> > >> a.zip(b).map {|i, j| i*j} > > > > this is indeed much more elegant. > > > > but because array * array is not defined, me thinks. one could implement > > (this simple case) this way. In APL, * and other operators work like this, element-by-element. > Here's a handy generalisation of the method: > > class Array > def mapwith(*args, &block) > if block_given? > zip(*args).collect {|i, j| yield i, j} > else > f = args.pop > zip(*args).collect {|i, j| i.send(f, j)} > end > end > end > > p [1,2,3].mapwith([4,5,6]) {|i,j| i*j} > p [1,2,3].mapwith([4,5,6], :*) Should #mapwith work with 3 or more arrays like #zip does? p [1,2,3].mapwith([4,5,6], [7,8,9]) {|i,j,k| i*j+k} Allowing #zip to take a block has been discussed before. Here's yet another implementation: class Array alias _zip zip def zip(*args) if block_given? _zip(*args).map {|a| yield a} else _zip(*args) end end end p [1,2,3].zip([4,5,6], [7,8,9]) {|i,j,k| i*j+k} Unfortunately, it doesn't allow taking a symbol to an operator (:*) like #mapwith does.