# Better name for #zip\_with

**URL:** <https://rubytalk.org/t/better-name-for-zip-with/63082>\
**Category:** ruby-talk\
**Created:** [18 July 2011 01:44 UTC](https://rubytalk.org/t/better-name-for-zip-with/63082 "2011-07-18T01:44:14Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [18 July 2011 01:44 UTC](https://rubytalk.org/t/better-name-for-zip-with/63082/1 "2011-07-18T01:44:14Z")

</div>

Any ideas for a better name for:

&nbsp;&nbsp;&nbsp;&nbsp;[1,2,3].zip\_with([6,5,4]) { |a, b| 3 \* a + b } #=\> [9, 11, 13]

#zip\_with comes from Haskell, but I think it's confusing because of  
Ruby's #zip.

---

<div class="post-metadata">

**Author:** ![John\_Feminella](https://avatars.discourse-cdn.com/v4/letter/j/9fc29f/32.png) [@John\_Feminella](https://rubytalk.org/u/John_Feminella)\
**Post date:** [18 July 2011 02:13 UTC](https://rubytalk.org/t/better-name-for-zip-with/63082/2 "2011-07-18T02:13:44Z")

</div>

Doesn't zip basically do that already?

ruby-1.9.2-p180 :001 \> l = [1,2,3]; r = [6,5,4]  
=\> [6, 5, 4]  
ruby-1.9.2-p180 :002 \> arr = []; l.zip(r) { |first, second| arr \<\< 3 \*  
first + second }; arr  
=\> [9, 11, 13]

(Are you just trying to save the last step?)

~ jf

> **···**
>
> --  
> John Feminella  
> Principal Consultant, BitsBuilder  
> LI: [http://www.linkedin.com/in/johnxf](http://www.linkedin.com/in/johnxf)  
> SO: [http://stackoverflow.com/users/75170/](http://stackoverflow.com/users/75170/)

---

<div class="post-metadata">

**Author:** ![Chris6](https://avatars.discourse-cdn.com/v4/letter/c/b2d939/32.png) [@Chris6](https://rubytalk.org/u/Chris6)\
**Post date:** [18 July 2011 02:16 UTC](https://rubytalk.org/t/better-name-for-zip-with/63082/3 "2011-07-18T02:16:11Z")

</div>

IT seems closer to map than zip (IMHO) so maybe map\_with ?  
OR would cross\_product cover it? Maybe too specific...

> **···**
>
> On Sun, Jul 17, 2011 at 9:44 PM, Intransition \<transfire@gmail.com\> wrote:
> 
> > Any ideas for a better name for:
> > 
> > [1,2,3].zip\_with([6,5,4]) { |a, b| 3 \* a + b } #=\> [9, 11, 13]
> > 
> > #zip\_with comes from Haskell, but I think it's confusing because of  
> > Ruby's #zip.

---

<div class="post-metadata">

**Author:** ![John\_Feminella](https://avatars.discourse-cdn.com/v4/letter/j/9fc29f/32.png) [@John\_Feminella](https://rubytalk.org/u/John_Feminella)\
**Post date:** [18 July 2011 02:36 UTC](https://rubytalk.org/t/better-name-for-zip-with/63082/4 "2011-07-18T02:36:09Z")

</div>

How about #zip\_and\_map? Notice that:

> a.zip\_with(b) { |c, d| ... }

is the same as the result of

> a.zip(b).map { |c, d| ... }

~ jf

> **···**
>
> --  
> John Feminella  
> Principal Consultant, BitsBuilder  
> LI: [http://www.linkedin.com/in/johnxf](http://www.linkedin.com/in/johnxf)  
> SO: [User John Feminella - Stack Overflow](http://stackoverflow.com/users/75170/)
> 
> On Sun, Jul 17, 2011 at 21:44, Intransition \<transfire@gmail.com\> wrote:
> 
> > Any ideas for a better name for:
> > 
> > [1,2,3].zip\_with([6,5,4]) { |a, b| 3 \* a + b } #=\> [9, 11, 13]
> > 
> > #zip\_with comes from Haskell, but I think it's confusing because of  
> > Ruby's #zip.

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [18 July 2011 03:28 UTC](https://rubytalk.org/t/better-name-for-zip-with/63082/5 "2011-07-18T03:28:37Z")

</div>

Actually, I didn't know zip took a block. Good to know. So yea, that  
makes it much closer than I realized. But why doesn't it map the  
results? That's unfortunate. I think I will submit a feature request  
for Ruby.

Thanks.

> **···**
>
> On Jul 17, 10:13 pm, John Feminella \<jo...@bitsbuilder.com\> wrote:
> 
> > Doesn't zip basically do that already?
> > 
> > ruby-1.9.2-p180 :001 \> l = [1,2,3]; r = [6,5,4]  
> > =\> [6, 5, 4]  
> > ruby-1.9.2-p180 :002 \> arr = ; l.zip(r) { |first, second| arr \<\< 3 \*  
> > first + second }; arr  
> > =\> [9, 11, 13]
> > 
> > (Are you just trying to save the last step?)

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [18 July 2011 03:30 UTC](https://rubytalk.org/t/better-name-for-zip-with/63082/6 "2011-07-18T03:30:03Z")

</div>

Ah, right. `#zip_map` would makes sense then. But per your last post,  
I think I may override #zip itself.

> **···**
>
> On Jul 17, 10:36 pm, John Feminella \<jo...@bitsbuilder.com\> wrote:
> 
> > How about #zip\_and\_map? Notice that:
> > 
> > \> a.zip\_with(b) { |c, d| ... }
> > 
> > is the same as the result of
> > 
> > \> a.zip(b).map { |c, d| ... }

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [18 July 2011 03:31 UTC](https://rubytalk.org/t/better-name-for-zip-with/63082/7 "2011-07-18T03:31:27Z")

</div>

#map\_with does read right, doesn't it. hmm...

> **···**
>
> On Jul 17, 10:16 pm, Chris Hulan \<chris.hu...@gmail.com\> wrote:
> 
> > IT seems closer to map than zip (IMHO) so maybe map\_with ?  
> > OR would cross\_product cover it? Maybe too specific...

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [18 July 2011 17:25 UTC](https://rubytalk.org/t/better-name-for-zip-with/63082/8 "2011-07-18T17:25:40Z")

</div>

Thomas Sawyer wrote in post #1011313:

> > How about #zip\_and\_map? Notice that:
> > 
> > \> a.zip\_with(b) { |c, d| ... }
> > 
> > is the same as the result of
> > 
> > \> a.zip(b).map { |c, d| ... }
> 
> Ah, right. `#zip_map` would makes sense then. But per your last post,  
> I think I may override #zip itself.

Not sure whether I find this a good idea. Reason: #map has overhead of  
creating a new Array with the same length as the input. That should not  
be the default behavior IMHO. A clean separation would be

.zip() =\> Enumerator  
.zip() {|a,b| ...} =\> nil (as today) or self (i.e. leftmost Array)

Then we can efficiently have .zip().map {|a,b| ...}

But it would break old code. ☹

So, today for efficient zip + map we would have to do

.enum\_for(:zip, ).map {|a,b| ...}

Kind regards

robert

> **···**
>
> > On Jul 17, 10:36pm, John Feminella \<jo...@bitsbuilder.com\> wrote:
> 
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Christopher\_Dicely](https://avatars.discourse-cdn.com/v4/letter/c/7c8e57/32.png) [@Christopher\_Dicely](https://rubytalk.org/u/Christopher_Dicely)\
**Post date:** [24 July 2011 06:24 UTC](https://rubytalk.org/t/better-name-for-zip-with/63082/9 "2011-07-24T06:24:14Z")

</div>

So, don't do that; just return an Enumerator that returns the  
successive results of applying the given block to the elements that  
would be returned by the Enumerator that would be returned by the  
non-block form of #zip.

> **···**
>
> On Mon, Jul 18, 2011 at 10:25 AM, Robert Klemme \<shortcutter@googlemail.com\> wrote:
> 
> > Thomas Sawyer wrote in post #1011313:
> > 
> > > On Jul 17, 10:36pm, John Feminella \<jo...@bitsbuilder.com\> wrote:
> > > 
> > > > How about #zip\_and\_map? Notice that:
> > > > 
> > > > \> a.zip\_with(b) { |c, d| ... }
> > > > 
> > > > is the same as the result of
> > > > 
> > > > \> a.zip(b).map { |c, d| ... }
> > > 
> > > Ah, right. `#zip_map` would makes sense then. But per your last post,  
> > > I think I may override #zip itself.
> > 
> > Not sure whether I find this a good idea. Reason: #map has overhead of  
> > creating a new Array with the same length as the input. That should not  
> > be the default behavior IMHO.

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [24 July 2011 23:16 UTC](https://rubytalk.org/t/better-name-for-zip-with/63082/10 "2011-07-24T23:16:59Z")

</div>

Thanks. If I add to Facets I'll utilize this.

I'm starting to think, however, that it makes more sense to add  
optional arguments to #map itself. Consider that #zip returns an assoc  
array, that's it's expected behavior. So it's probably best not to  
alter that. Whereas map can return any form of array based on the  
block.

&nbsp;&nbsp;&nbsp;&nbsp;[1,2,3].map([2,3,4], [5,6,7]) { |a,b,c| ... }

Map has free arguments, so why not?

> **···**
>
> On Jul 18, 1:25 pm, Robert Klemme \<shortcut...@googlemail.com\> wrote:
> 
> > Thomas Sawyer wrote in post #1011313:
> > 
> > \> On Jul 17, 10:36pm, John Feminella \<jo...@bitsbuilder.com\> wrote:  
> > \>\> How about #zip\_and\_map? Notice that:
> > 
> > \>\> \> a.zip\_with(b) { |c, d| ... }
> > 
> > \>\> is the same as the result of
> > 
> > \>\> \> a.zip(b).map { |c, d| ... }
> > 
> > \> Ah, right. `#zip_map` would makes sense then. But per your last post,  
> > \> I think I may override #zip itself.
> > 
> > Not sure whether I find this a good idea. Reason: #map has overhead of  
> > creating a new Array with the same length as the input. That should not  
> > be the default behavior IMHO. A clean separation would be
> > 
> > .zip() =\> Enumerator  
> > .zip() {|a,b| ...} =\> nil (as today) or self (i.e. leftmost Array)
> > 
> > Then we can efficiently have .zip().map {|a,b| ...}
> > 
> > But it would break old code. ☹
> > 
> > So, today for efficient zip + map we would have to do
> > 
> > .enum\_for(:zip, ).map {|a,b| ...}

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [24 July 2011 16:57 UTC](https://rubytalk.org/t/better-name-for-zip-with/63082/11 "2011-07-24T16:57:14Z")

</div>

What exactly do you mean? #to\_enum does not honor a block:

irb(main):001:0\> a=5.times.to\_a  
=\> [0, 1, 2, 3, 4]  
irb(main):002:0\> b=a.to\_enum(:map) {|x|x\*2}  
=\> #\<Enumerator: [0, 1, 2, 3, 4]:map\>  
irb(main):003:0\> b.to\_a  
=\> [0, 1, 2, 3, 4]

Did you mean Generator?

irb(main):012:0\> b=Enumerator.new {|y| a.each {|x| y \<\< x\*2}}  
=\> #\<Enumerator: #\<Enumerator::Generator:0x106afc60\>:each\>  
irb(main):013:0\> b.to\_a  
=\> [0, 2, 4, 6, 8]

With #zip

irb(main):014:0\> b=a.dup  
=\> [0, 1, 2, 3, 4]  
irb(main):015:0\> i=Enumerator.new {|y| a.zip(b){|m,n| y \<\< m - n} }  
=\> #\<Enumerator: #\<Enumerator::Generator:0x1066d248\>:each\>  
irb(main):016:0\> i.to\_a  
=\> [0, 0, 0, 0, 0]

Kind regards

robert

> **···**
>
> On Sun, Jul 24, 2011 at 8:24 AM, Christopher Dicely \<cmdicely@gmail.com\> wrote:
> 
> > On Mon, Jul 18, 2011 at 10:25 AM, Robert Klemme \> \<shortcutter@googlemail.com\> wrote:
> > 
> > > Thomas Sawyer wrote in post #1011313:
> > > 
> > > > On Jul 17, 10:36pm, John Feminella \<jo...@bitsbuilder.com\> wrote:
> > > > 
> > > > > How about #zip\_and\_map? Notice that:
> > > > > 
> > > > > \> a.zip\_with(b) { |c, d| ... }
> > > > > 
> > > > > is the same as the result of
> > > > > 
> > > > > \> a.zip(b).map { |c, d| ... }
> > > > 
> > > > Ah, right. `#zip_map` would makes sense then. But per your last post,  
> > > > I think I may override #zip itself.
> > > 
> > > Not sure whether I find this a good idea. Reason: #map has overhead of  
> > > creating a new Array with the same length as the input. That should not  
> > > be the default behavior IMHO.
> > 
> > So, don't do that; just return an Enumerator that returns the  
> > successive results of applying the given block to the elements that  
> > would be returned by the Enumerator that would be returned by the  
> > non-block form of #zip.
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [25 July 2011 07:11 UTC](https://rubytalk.org/t/better-name-for-zip-with/63082/12 "2011-07-25T07:11:57Z")

</div>

> I'm starting to think, however, that it makes more sense to add  
> optional arguments to #map itself. Consider that #zip returns an assoc  
> array, that's it's expected behavior. So it's probably best not to  
> alter that. Whereas map can return any form of array based on the  
> block.
> 
> [1,2,3].map([2,3,4], [5,6,7]) { |a,b,c| ... }

Wouldn't that be

[1,2,3].map([2,3,4], [5,6,7]) { |a,b| ... }

?

> Map has free arguments, so why not?

Orthogonality probably. And it is not entirely clear whether map +  
zip is the most common or most useful use. Others may want to use  
arguments to #map for #grep like selection or even other uses. Who  
decides which use wins and becomes standard?

Kind regards

robert

> **···**
>
> On Mon, Jul 25, 2011 at 1:16 AM, Intransition \<transfire@gmail.com\> wrote:
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)

---

<div class="post-metadata">

**Author:** ![Adam\_Prescott](https://avatars.discourse-cdn.com/v4/letter/a/7feea3/32.png) [@Adam\_Prescott](https://rubytalk.org/u/Adam_Prescott)\
**Post date:** [25 July 2011 08:03 UTC](https://rubytalk.org/t/better-name-for-zip-with/63082/13 "2011-07-25T08:03:38Z")

</div>

What about cutting to the point of the method and calling it #zip\_map (first  
zip, then map)? It isn't as readable but it avoids the misleading parts of  
#zip\_with and the introduction of zipping functionality to #map.
