https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112011-11-23T05:43:58ZRuby Issue Tracking SystemRuby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=223342011-11-23T05:43:58Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>I like the idea but not the name. Maybe something like select_non_nil would be more appropriate. English is not my mother tongue, is there any English way to say this in a shorter way?</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=223362011-11-23T05:45:04Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Or maybe just enum.filter?</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=223372011-11-23T06:23:06Zaprescott (Adam Prescott)
<ul></ul><p>Instead of looking at it from the map + select approach for a name, what<br>
about the map + compact version? compact_map ?</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=223382011-11-23T06:53:10Zwycats (Yehuda Katz)wycats@gmail.com
<ul></ul><p>Compact implies two passes, no?</p>
<p>Yehuda Katz<br>
(ph) 718.877.1325</p>
<p>On Tue, Nov 22, 2011 at 1:15 PM, Adam Prescott <a href="mailto:adam@aprescott.com" class="email">adam@aprescott.com</a> wrote:</p>
<blockquote>
<p>Instead of looking at it from the map + select approach for a name, what<br>
about the map + compact version? compact_map ?</p>
</blockquote> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=223392011-11-23T07:29:07Zshugo (Shugo Maeda)
<ul><li><strong>ruby -v</strong> changed from <i>ruby 1.9.3p0 (2011-11-08 revision 33661) [x86_64-darwin11.2.0]</i> to <i>-</i></li></ul><p>Hi,</p>
<p>2011/11/23 Yehuda Katz <a href="mailto:wycats@gmail.com" class="email">wycats@gmail.com</a>:</p>
<blockquote>
<p>It is pretty common to want to map over an Enumerable, but only include the elements that match a particular filter. A common idiom is:</p>
<p>enum.map { |i| i + 1 if i.even? }.compact</p>
<p>It is of course also possible to do this with two calls:</p>
<p>enum.select { |i| i.even? }.map { |i| i + 1 }</p>
<p>Both cases are clumsy and require two iterations through the loop. I'd like to propose a combined method:</p>
<p>enum.map_select { |i| i + 1 if i.even? }</p>
<p>The only caveat is that it would be impossible to intentionally return nil here; suggestions welcome. The naming is also a strawman; feel free to propose something better.</p>
</blockquote>
<p>How about to add list comprehensions or Scala's for expressions instead?<br>
For example, <code>enum.select { |i| i.even? }.map { |i| i + 1 }</code> can be<br>
written as follows:</p>
<p>[ i + 1 for i in enum if i.even? ]</p>
<a name="The-syntax-of-list-comprehensions-needs-more-considerations"></a>
<h1 >The syntax of list comprehensions needs more considerations.<a href="#The-syntax-of-list-comprehensions-needs-more-considerations" class="wiki-anchor">¶</a></h1>
<p>One benefit is that nested maps can be flattened by list comprehensions.<br>
For example, the following code:</p>
<p>pyths = [ [x, y, z] for z in [1..Float::INFINITY].defer<br>
x in [1..z].defer<br>
y in [x..z].defer<br>
if x<strong>2 + y</strong>2 == z**2 ]<br>
p pyths.take(3)</p>
<p>is equivalent to the following code:</p>
<p>pyths = (1..Float::INFINITY).defer.flat_map {|z|<br>
(1..z).defer.flat_map {|x|<br>
(x..z).defer.select {|y|<br>
x<strong>2 + y</strong>2 == z**2<br>
}.map {|y|<br>
[x, y, z]<br>
}<br>
}<br>
}<br>
p pyths.take(3)</p>
<a name="Enumerabledefer-is-proposed-in-Feature-4890"></a>
<h1 >Enumerable#defer is proposed in Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Enumerable#lazy (Closed)" href="https://redmine.ruby-lang.org/issues/4890">#4890</a>.<a href="#Enumerabledefer-is-proposed-in-Feature-4890" class="wiki-anchor">¶</a></h1>
<p>BTW, now Ruby has map and reduce as aliases of collect and inject,<br>
but not filter as an alias of select. Why not?</p>
<p>--<br>
Shugo Maeda</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=223402011-11-23T07:31:44Znahi (Hiroshi Nakamura)nakahiro@gmail.com
<ul><li><strong>Tracker</strong> changed from <i>Bug</i> to <i>Feature</i></li></ul><p>Bug -> Feature</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=223472011-11-23T08:55:02Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Hi Shugo, I also like the idea of supporting list comprehensions like several other languages currently do.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=223502011-11-23T09:23:08Zwycats (Yehuda Katz)wycats@gmail.com
<ul></ul><p>I am nervous about list comprehensions because in almost all cases, when<br>
you do something in Ruby, you do it by invoking a named method on an<br>
object. It is clear by looking at a piece of code which named method will<br>
be invoked. In Ruby 1.9, it is even trivial to learn the exact source<br>
location of such a named method.</p>
<p>In contrast, list comprehensions introduce new syntax that invokes some<br>
invisible protocol; understanding which methods are involved requires<br>
figuring out where to look in the documentation.</p>
<p>Python uses protocols like this for <em>everything</em>, so list comprehensions<br>
fit in well there. The only Ruby case I can think of that works like this<br>
is the much maligned for/in syntax, which invokes #each under the hood.<br>
Most people I know find this strange, I suspect because of its<br>
inconsistency with the very strong rule that if a method is directly<br>
invoked by some syntax, you can see it.</p>
<p>If you want to see where this protocol-oriented path leads us, check out<br>
<a href="http://docs.python.org/reference/datamodel.html#special-method-names" class="external">http://docs.python.org/reference/datamodel.html#special-method-names</a>. I<br>
much prefer Ruby's "if you want to do something, invoke a named method"<br>
principle of uniform access[1].</p>
<p>[1] <a href="http://en.wikipedia.org/wiki/Uniform_access_principle" class="external">http://en.wikipedia.org/wiki/Uniform_access_principle</a></p>
<p>Yehuda Katz<br>
(ph) 718.877.1325</p>
<p>On Tue, Nov 22, 2011 at 2:26 PM, Shugo Maeda <a href="mailto:shugo@ruby-lang.org" class="email">shugo@ruby-lang.org</a> wrote:</p>
<blockquote>
<p>Hi,</p>
<p>2011/11/23 Yehuda Katz <a href="mailto:wycats@gmail.com" class="email">wycats@gmail.com</a>:</p>
<blockquote>
<p>It is pretty common to want to map over an Enumerable, but only include<br>
the elements that match a particular filter. A common idiom is:</p>
<p>enum.map { |i| i + 1 if i.even? }.compact</p>
<p>It is of course also possible to do this with two calls:</p>
<p>enum.select { |i| i.even? }.map { |i| i + 1 }</p>
<p>Both cases are clumsy and require two iterations through the loop. I'd<br>
like to propose a combined method:</p>
<p>enum.map_select { |i| i + 1 if i.even? }</p>
<p>The only caveat is that it would be impossible to intentionally return<br>
nil here; suggestions welcome. The naming is also a strawman; feel free to<br>
propose something better.</p>
</blockquote>
<p>How about to add list comprehensions or Scala's for expressions instead?<br>
For example, enum.select { |i| i.even? }.map { |i| i + 1 } can be<br>
written as follows:</p>
<p>[ i + 1 for i in enum if i.even? ]</p>
<a name="The-syntax-of-list-comprehensions-needs-more-considerations"></a>
<h1 >The syntax of list comprehensions needs more considerations.<a href="#The-syntax-of-list-comprehensions-needs-more-considerations" class="wiki-anchor">¶</a></h1>
<p>One benefit is that nested maps can be flattened by list comprehensions.<br>
For example, the following code:</p>
<p>pyths = [ [x, y, z] for z in [1..Float::INFINITY].defer<br>
x in [1..z].defer<br>
y in [x..z].defer<br>
if x<strong>2 + y</strong>2 == z**2 ]<br>
p pyths.take(3)</p>
<p>is equivalent to the following code:</p>
<p>pyths = (1..Float::INFINITY).defer.flat_map {|z|<br>
(1..z).defer.flat_map {|x|<br>
(x..z).defer.select {|y|<br>
x<strong>2 + y</strong>2 == z**2<br>
}.map {|y|<br>
[x, y, z]<br>
}<br>
}<br>
}<br>
p pyths.take(3)</p>
<a name="Enumerabledefer-is-proposed-in-Feature-4890"></a>
<h1 >Enumerable#defer is proposed in Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Enumerable#lazy (Closed)" href="https://redmine.ruby-lang.org/issues/4890">#4890</a>.<a href="#Enumerabledefer-is-proposed-in-Feature-4890" class="wiki-anchor">¶</a></h1>
<p>BTW, now Ruby has map and reduce as aliases of collect and inject,<br>
but not filter as an alias of select. Why not?</p>
<p>--<br>
Shugo Maeda</p>
</blockquote> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=223612011-11-23T19:33:05Zalexeymuranov (Alexey Muranov)
<ul></ul><p>It seems that in full generality this method needs to accept two blocks: one for selecting and one for mapping, but this would be an unusual syntax.</p>
<p>So how about a lazy <code>#selecting</code> first, which would store a block for selecting inside <code>enum</code>, and to make <code>#map</code> check if a block for selecting is defined, and to use it? Maybe, instead of changing <code>#map</code>, a new variant of <code>#map</code> can be created that would take lazy operations into account. (For the name, i would propose <code>#partial_map</code> or <code>#map_partially</code> ( <a href="http://en.wikipedia.org/wiki/Partial_function" class="external">http://en.wikipedia.org/wiki/Partial_function</a> ), or <code>#map_selected</code>.) Then the code would look like this:</p>
<p>enum.selecting { |i| i.even? }.map_selected { |i| i + 1 }</p>
<p>and only one loop will be needed.</p>
<p>I've read about gems defining lazy methods for Enumerable, but i do not remember if any of them is doing exactly this.<br>
<em>Update</em> Here is a link to a description of Lazing project:<br>
<a href="http://blog.gregspurrier.com/articles/lazing-lazy-enumerable-methods-for-ruby-1-9" class="external">http://blog.gregspurrier.com/articles/lazing-lazy-enumerable-methods-for-ruby-1-9</a></p>
<p>-Alexey.</p>
<hr>
<p><em>Update</em> If the goal is not to solve this in full generality, but to optimize for one use case, then what about #map_and_compact ? I think it is ok to have relatively long names for methods that solve relatively restricted problems.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=223672011-11-24T00:21:27Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Alexey, what about thread safety in this case? Would the selecting return a new object?</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=223692011-11-24T01:53:42Zalexeymuranov (Alexey Muranov)
<ul></ul><p>Rodrigo Rosenfeld Rosas wrote:</p>
<blockquote>
<p>Alexey, what about thread safety in this case? Would the selecting return a new object?</p>
</blockquote>
<p>I do not know much about threads. I think <code>#selecting</code> can return a new object, and <code>#selecting!</code> can add lazy selection to the object on which it is called. Those more knowledgable please comment with something wiser.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=223862011-11-24T09:54:53Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>I was just suggesting that maybe avoiding laziness for this case would be less of a trouble since we wouldn't need to worry about thread safety...</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=223982011-11-24T16:12:17Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Category</strong> set to <i>lib</i></li><li><strong>Target version</strong> set to <i>2.0.0</i></li></ul><p>=begin<br>
What about:<br>
(1..10).grep(->(i){i.even?}){|i|i+1}<br>
or<br>
(1..10).grep(:even?.to_proc){|i|i+1}<br>
=end</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=224002011-11-24T17:49:22Ztrans (Thomas Sawyer)
<ul></ul><p>Related methods:</p>
<ul>
<li>filter (<a href="http://rubyworks.github.com/facets/doc/api/core/Enumerable.html#method-i-filter" class="external">http://rubyworks.github.com/facets/doc/api/core/Enumerable.html#method-i-filter</a>)</li>
<li>purge (<a href="http://rubyworks.github.com/facets/doc/api/core/Enumerable.html#method-i-purge" class="external">http://rubyworks.github.com/facets/doc/api/core/Enumerable.html#method-i-purge</a>)</li>
</ul> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=224052011-11-24T20:41:11Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Nobuyoshi, wouldn't &:even? be equivalent to :even?.to_proc? I just find that the example reads better this way ;)</p>
<p>(1..10).grep(&:even?){|i|i+1}</p>
<p>But anyway, I don't find that "grep" is self-explanatory, although I like the idea of passing two procs.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=224062011-11-24T20:43:50Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>How can I find the syntax for highlighting the code in this Redmine instance?</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=224132011-11-25T12:00:55Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Rodrigo Rosenfeld Rosas wrote:</p>
<blockquote>
<p>Nobuyoshi, wouldn't &:even? be equivalent to :even?.to_proc? I just find that the example reads better this way ;)</p>
</blockquote>
<p>They are different.<br>
&expr calls #to_proc method on the result of expr, to achieve a Proc object.</p>
<blockquote>
<p>(1..10).grep(&:even?){|i|i+1}</p>
</blockquote>
<p>It's a syntax error.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=224512011-11-28T10:23:28Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Em 25-11-2011 01:00, Nobuyoshi Nakada escreveu:</p>
<blockquote>
<p>Issue <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Combined map/select method (Closed)" href="https://redmine.ruby-lang.org/issues/5663">#5663</a> has been updated by Nobuyoshi Nakada.</p>
<p>Rodrigo Rosenfeld Rosas wrote:</p>
<blockquote>
<p>Nobuyoshi, wouldn't&:even? be equivalent to :even?.to_proc? I just find that the example reads better this way ;)<br>
They are different.<br>
&expr calls #to_proc method on the result of expr, to achieve a Proc object.</p>
</blockquote>
<blockquote>
<p>(1..10).grep(&:even?){|i|i+1}<br>
It's a syntax error.</p>
</blockquote>
</blockquote>
<p>Wow! Thanks! This is unexpected to me. I didn't know about the difference.</p>
<p>Anyway, I still didn't understand why (1..10).grep(&:even?) works, but<br>
(1..10).grep(&:even?){|i| i+1} not.</p>
<p>Actually, I didn't understand your explanation. You said that &expr<br>
calls #to_proc on the result of expr. What is the expr on each example?<br>
Is there any place I could further read about those differences?</p>
<p>Thank you, Rodrigo.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=224572011-11-28T11:23:14Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Hi,</p>
<p>(11/11/28 10:05), Rodrigo Rosenfeld Rosas wrote:</p>
<blockquote>
<blockquote>
<p>&expr calls #to_proc method on the result of expr, to achieve a Proc object.</p>
</blockquote>
</blockquote>
<p>achieve a Proc object, and convert it into a block.</p>
<blockquote>
<p>Anyway, I still didn't understand why (1..10).grep(&:even?) works, but (1..10).grep(&:even?){|i| i+1} not.</p>
</blockquote>
<p>The former is equivalent to</p>
<p>(1..10).grep {|i| i.even?}</p>
<p>You can't pass two or more blocks to one method call.</p>
<blockquote>
<p>Actually, I didn't understand your explanation. You said that &expr calls #to_proc on the result of expr. What is the expr on each example? Is there any place I could further read about those differences?</p>
</blockquote>
<p>expr is :even? symbol literal here.</p>
<p>--<br>
Nobu Nakada</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=224672011-11-28T21:53:08Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Em 27-11-2011 23:59, Nobuyoshi Nakada escreveu:</p>
<blockquote>
<p>...</p>
<blockquote>
<p>Anyway, I still didn't understand why (1..10).grep(&:even?) works, but (1..10).grep(&:even?){|i| i+1} not.<br>
The former is equivalent to</p>
</blockquote>
<p>(1..10).grep {|i| i.even?}</p>
<p>You can't pass two or more blocks to one method call.</p>
</blockquote>
<p>Ah, ok, thanks. So this is actually the explanation why the other<br>
example won't work.</p>
<p>Maybe if Ruby accepted blocks as parameters, like Groovy does and as<br>
José Valim has proposed in a talk at RubyConf Brazil, that could be<br>
achievable as</p>
<p>(1..10).grep&:even?, {|i| i+1}</p>
<p>Has this feature already been discussed?</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=224822011-11-29T08:30:21Zalexeymuranov (Alexey Muranov)
<ul></ul><p>Rodrigo Rosenfeld Rosas wrote:</p>
<blockquote>
<p>Em 25-11-2011 01:00, Nobuyoshi Nakada escreveu:</p>
<blockquote>
<p>Issue <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Combined map/select method (Closed)" href="https://redmine.ruby-lang.org/issues/5663">#5663</a> has been updated by Nobuyoshi Nakada.</p>
<p>Rodrigo Rosenfeld Rosas wrote:</p>
<blockquote>
<p>Nobuyoshi, wouldn't&:even? be equivalent to :even?.to_proc? I just find that the example reads better this way ;)<br>
They are different.<br>
&expr calls #to_proc method on the result of expr, to achieve a Proc object.</p>
</blockquote>
<blockquote>
<p>(1..10).grep(&:even?){|i|i+1}<br>
It's a syntax error.</p>
</blockquote>
</blockquote>
<p>Wow! Thanks! This is unexpected to me. I didn't know about the difference.</p>
<p>Anyway, I still didn't understand why (1..10).grep(&:even?) works, but<br>
(1..10).grep(&:even?){|i| i+1} not.</p>
<p>Actually, I didn't understand your explanation. You said that &expr<br>
calls #to_proc on the result of expr. What is the expr on each example?<br>
Is there any place I could further read about those differences?</p>
<p>Thank you, Rodrigo.</p>
</blockquote>
<p>I am not a specialist, but it seems that you can only use ampersand in a <code>def</code> with the <em>last</em> parameter, and in such case this last parameter becomes the name of a block passed to the method. Similarly, when you call a method, you can either supply a block, or pass a proc as a block by adding it as the last argument prefixed with ampersand, but not both, because you cannot pass two blocks to a method (but you can pass multiple procs). So basically only one ampersand is allowed, and only if you do not supply a block.</p>
<p>Here is a link about blocks and procs, but it does not explain this detail:<br>
<a href="http://www.robertsosinski.com/2008/12/21/understanding-ruby-blocks-procs-and-lambdas/" class="external">http://www.robertsosinski.com/2008/12/21/understanding-ruby-blocks-procs-and-lambdas/</a></p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=224882011-11-29T20:32:00Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Hi Alexey,</p>
<p>Yes, I know about this. What José Valim suggested (well, he actually wondered, since he doesn't believe this could be changed in Ruby due to the large existent code base) was the removal of the block concept. From what I've understood, the block syntax would actually create a proc (or a lambda) that would be passed as a parameter. And I also find this less confusing, with the similar callable approach taken by C, JavaScript, Python and most languages out there I guess.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=225122011-12-01T05:29:08Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Em 30-11-2011 05:41, Ondřej Bílka escreveu:</p>
<blockquote>
<p>On Tue, Nov 29, 2011 at 08:32:01PM +0900, Rodrigo Rosenfeld Rosas wrote:</p>
<blockquote>
<p>... What José Valim suggested (well, he actually wondered, since he doesn't believe this could be changed in Ruby due to the large existent code base) was the removal of the block concept. From what I've understood, the block syntax would actually create a proc (or a lambda) that would be passed as a parameter. And I also find this less confusing, with the similar callable approach taken by C, JavaScript, Python and most languages out there I guess.<br>
It already is. For example<br>
def foo(&p)<br>
p.call<br>
end</p>
</blockquote>
</blockquote>
<p>This is not what I'm talking about. The other callable languages<br>
wouldn't have special treatments for blocks like block_given? or yield,<br>
for instance.</p>
<p>I'm talking about "method(some_param){some_block 'here'}" being exactly<br>
equal to "method some_param, lambda {some_block 'here'}" (or using a<br>
proc instead of a lambda, I'm not sure about which one would be a better<br>
fit).</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=229962011-12-29T12:03:48Zkernigh (George Koehler)xkernigh@netscape.net
<ul></ul><p>=begin<br>
Nobuyoshi Nakada wrote:</p>
<blockquote>
<p>What about:<br>
(1..10).grep(->(i){i.even?}){|i|i+1}<br>
or<br>
(1..10).grep(:even?.to_proc){|i|i+1}</p>
</blockquote>
<p>This looks smart. One can also write it as<br>
(1..10).grep((proc &:even?), &:succ)<br>
but that might be too ugly.</p>
<p>I forgot about #grep, so I would have used #flat_map:<br>
(1..10).flat_map{|i| i.even?? [i + 1] : []}</p>
<p>I like #flat_map, but it might have a disadvantage: it must allocate several new zero-element and one-element arrays.<br>
=end</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=234672012-02-01T02:53:15ZAnonymous
<ul></ul><blockquote>
<p>It is pretty common to want to map over an Enumerable, but only include the elements that match a particular filter. A common idiom is:</p>
<p>enum.map { |i| i + 1 if i.even? }.compact</p>
<p>It is of course also possible to do this with two calls:</p>
<p>enum.select { |i| i.even? }.map { |i| i + 1 }</p>
<p>Both cases are clumsy and require two iterations through the loop. I'd like to propose a combined method:</p>
</blockquote>
<p>+1 for a combined map and select. I find myself reaching for it every<br>
so often and wishing it were there.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=234792012-02-01T11:18:56Ztrans (Thomas Sawyer)
<ul></ul><p>In Facets it's called #compact_map, but that's only b/c I thought better of monkey patching #compact itself.</p>
<p>I think it would be a slick feature for #compact to take a block.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=234802012-02-01T11:23:13Ztrans (Thomas Sawyer)
<ul></ul><p>In Facets it's called #compact_map, but that's only b/c I though better of<br>
monkey patching #compact itself.</p>
<p>I think it would be a slick addition for #compact to take a block.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=234812012-02-01T12:53:56Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Hi,</p>
<p>(12/02/01 11:18), Thomas Sawyer wrote:</p>
<blockquote>
<p>In Facets it's called #compact_map, but that's only b/c I thought better of monkey patching #compact itself.</p>
<p>I think it would be a slick feature for #compact to take a block.</p>
</blockquote>
<p>Mere "compact" doesn't feel implying "map".</p>
<p>--<br>
Nobu Nakada</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=234832012-02-01T13:10:37Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<ul></ul><p>I often wish to have methods, which likes to <code>inject</code> but do use return value of block for next iteration:</p>
<pre><code>class Enumerable
def accum(container)
each{|args| yield container, args}
container
end
end
</code></pre>
<p>Then I could use it in following ways:<br>
instead of</p>
<pre><code>enum.inject({}){|h, k| h[k] = true; h}
enum.map{|ar| ar.select{|i| i.usefull?}}.flatten(1)
enum.map{|i| i + 1 if i.even?}.compact
</code></pre>
<p>I could</p>
<pre><code>enum.accum({}){|h,k| h[k] = true}
enum.accum([]){|res, ar| ar.each{|i| res << i if i.usefull?}}
enum.accum([]){|res, i| res << i + 1 if i.even?}
</code></pre>
<p>Well, it is shorter only in case of <code>inject</code>, but I still will prefer such method, cause I don't stress GC with many short living arrays.<br>
And maybe two common <code>container</code>-s could have separate methods:</p>
<pre><code>class Enumerable
def accum_hash(&block)
accum({}, &block)
end
def accum_ar(&block)
accum([], &block)
end
end
enum.accum_hash{|h,k| h[k] = true}
enum.accum_array{|res, ar| ar.each{|i| res << i if i.usefull?}}
enum.accum_array{|res, i| res << i + 1 if i.even?}
</code></pre> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=234842012-02-01T14:11:08Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Yura Sokolov wrote:</p>
<blockquote>
<p>I often wish to have methods, which likes to <code>inject</code> but do use return value of block for next iteration:</p>
</blockquote>
<p>Try each_with_object.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=234912012-02-01T20:41:43Ztrans (Thomas Sawyer)
<ul></ul><p>@Nakada Why not?</p>
<p>"Returns a copy of self with all nil elements removed. If block is given, returns the yield of each member sans those that yield nil."</p>
<p>[1,2,3,4].compact{ |x| x.even? ? x*2 : nil } #=> [4,16]</p>
<p>Seems clear enough to me. Besides, I think we'd be quite hard pressed to find some other term that implies both "map" and "compact".</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=237532012-02-13T20:12:39Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Rejected</i></li></ul><p>In <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Lazy Enumerator#select, Enumerator#map etc. (Rejected)" href="https://redmine.ruby-lang.org/issues/708">#708</a>, Matz approved a related ticket <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Enumerable#lazy (Closed)" href="https://redmine.ruby-lang.org/issues/4890">#4890</a>.<br>
Let's discuss there.</p>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@tsg.ne.jp" class="email">mame@tsg.ne.jp</a></p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=237572012-02-13T20:43:39Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>I don't think <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Enumerable#lazy (Closed)" href="https://redmine.ruby-lang.org/issues/4890">#4890</a> removes the need for this ticket. This is about API, not implementation. Even if we can use lazy maps/collects to implement this API, I still think it should exist.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=237592012-02-13T20:51:58Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Rejected</i> to <i>Assigned</i></li><li><strong>Assignee</strong> set to <i>matz (Yukihiro Matsumoto)</i></li></ul><p>Okay reopened.</p>
<p>Do you mean we need map_select as a shorthand?</p>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@tsg.ne.jp" class="email">mame@tsg.ne.jp</a></p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=237632012-02-13T21:09:03Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Yes, Yusuke, exactly. Thanks for reopening.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=237852012-02-14T00:30:20Ztrans (Thomas Sawyer)
<ul></ul><p>One of the problems with this method is that in becomes impossible to get <code>nil</code> or <code>false</code> as a valid selection/non-compaction.</p>
<p>Couple thoughts on handling this. For starters maybe #compact should be able to take an argument, e.g.</p>
<p>[1,2,3,1].compact(1) => [2,3]</p>
<p>(This in itself seems pretty useful, regardless.)</p>
<p>Then a #compact_map could do the same. If we need to be able to get nil/false results we could then use an alternative.</p>
<p>foo = Object.new</p>
<p>[0,1,-1].compact_map(foo){ |e| e.zero? ? foo : (e > 0 ? true : false) } #=> [true,false]</p>
<p>(Here's a case where some sort of global <code>null</code> instance might be useful, in place of <code>foo</code>.)</p>
<p>But then again, a delayed enumeration is about as concise, and maybe a bit easier to read.</p>
<p>[0,1,-1].denum.select{ |e| !e.zero? }.map{ |e| e > 0 ? true : false }.to_a #=> [true,false]</p>
<p>Something to consider.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=237932012-02-14T04:45:05Zjballanc (Joshua Ballanco)jballanc@gmail.com
<ul></ul><p>What about using "next" for this purpose? Currently:</p>
<blockquote>
<p>(1..10).to_a.map { |i| i % 3 == 0 ? next : i**2 }<br>
=> [1, 4, nil, 16, 25, nil, 49, 64, nil, 100]</p>
</blockquote>
<p>Is it so common to use "next" with a return value inside of an Enumerable#map call? Even so, could we special case "next" so that instead of returning nil, it skips the element entirely?</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=237952012-02-14T05:17:22Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Thomas, I didn't find your example for justifying a "null" instance good enough. Why not just using "nil" instead of "foo"?</p>
<p>But I liked your suggestion on "compact" allowing an argument defaulting to nil.</p>
<p>Joshua, I like the idea of next inside a map doing the compact thing, but I guess this will be hard to get approval for from Ruby Core team.</p>
<p>It would be a surprising feature in Ruby. Ruby is usually a pretty concise language with very little surprises... I'm not sure if they'll want to introduce such different "next" behavior only for the map/collect method.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=237992012-02-14T05:48:06Ztrans (Thomas Sawyer)
<ul></ul><p>@rodrigo</p>
<p>Your right, I could have used nil, so my example wasn't a particularly good one for what I was trying to demonstrate. Here's a better demonstration:</p>
<p>[0,1,-1,2].compact_map(foo) do |e|<br>
case e<br>
when 0 then nil<br>
when 1 then true<br>
when -1 then false<br>
else foo<br>
end<br>
end<br>
#=> [nil,true,false]</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=238002012-02-14T05:52:52Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>I supposed that was your point, but I waited for your new example, before talking about this.</p>
<p>The point is that usually we want some examples from the real world for considering some feature.</p>
<p>So, I don't find this example likely to actually happen on real software. Could you please provide some real scenario where having nils in the result would be better than any other values?</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=242912012-03-05T11:47:00Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<ul></ul><p>2012/2/1 Nobuyoshi Nakada <a href="mailto:nobu@ruby-lang.org" class="email">nobu@ruby-lang.org</a></p>
<blockquote>
<p>Issue <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Combined map/select method (Closed)" href="https://redmine.ruby-lang.org/issues/5663">#5663</a> has been updated by Nobuyoshi Nakada.</p>
<p>Yura Sokolov wrote:</p>
<blockquote>
<p>I often wish to have methods, which likes to <code>inject</code> but do use return<br>
value of block for next iteration:</p>
</blockquote>
<p>Try each_with_object.</p>
</blockquote>
<p>Yeah, it is good :) though it have a long name.</p>
<p>Yura</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=255452012-04-01T02:39:03Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Feedback</i></li></ul><p>I am OK with the original map_select behavior, but I don't like the name #map_select.<br>
It is combination of -ect family name with map.</p>
<p>I prefer the name #filter, but it might be confused by simple alias of select.<br>
Any idea?</p>
<p>Matz.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=255632012-04-01T11:18:16Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>I actually prefer map_select as it is self-explanatory. There isn't a single word that is able to clearly provide the description for what it does.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=255642012-04-01T11:53:12Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Hi,</p>
<p>(12/02/01 18:14), Юрий Соколов wrote:</p>
<blockquote>
<blockquote>
<p>Try each_with_object.</p>
</blockquote>
<p>Yeah, it is good :) though it have a long name. It's pity that 1.9.3 hadn't<br>
it.</p>
</blockquote>
<p>It's long indeed, but 1.9.3 had it.</p>
<p>$ ./ruby -v -e 'p((1..3).each_with_object({}){|x,a|a[x]=x+1})'<br>
ruby 1.9.3p0 (2011-10-30 revision 33569) [x86_64-darwin11.3.0]<br>
{1=>2, 2=>3, 3=>4}</p>
<p>--<br>
Nobu Nakada</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=255722012-04-02T02:40:08Ztrans (Thomas Sawyer)
<ul></ul><p>Maybe <code>#select_yield</code>, since that what it is doing.</p>
<p>Which reminds me, is there an equivalent <code>#find</code> method to this (e.g. <code>#find_yield</code>), that returns the yield result instead of the element?</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=258722012-04-13T11:21:36Zshugo (Shugo Maeda)
<ul></ul><p>matz (Yukihiro Matsumoto) wrote:</p>
<blockquote>
<p>I am OK with the original map_select behavior, but I don't like the name #map_select.<br>
It is combination of -ect family name with map.</p>
<p>I prefer the name #filter, but it might be confused by simple alias of select.<br>
Any idea?</p>
</blockquote>
<p>I think filter should be a simple alias of select.</p>
<a name="Otherwise-we-cant-complain-about-Scalas-collectp"></a>
<h1 >Otherwise, we can't complain about Scala's collect:p<a href="#Otherwise-we-cant-complain-about-Scalas-collectp" class="wiki-anchor">¶</a></h1>
<p>How about filter_map?</p>
<p>I've found that Scheme has filter-map.<br>
From SRFI-1:</p>
<p>filter-map f clist1 clist2 ... -> list<br>
Like map, but only true values are saved.<br>
(filter-map (lambda (x) (and (number? x) (* x x))) '(a 1 b 3 c 7))<br>
=> (1 9 49)<br>
The dynamic order in which the various applications of f are made is not specified.<br>
At least one of the list arguments must be finite.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=258822012-04-13T20:51:20Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>+1</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=269082012-05-31T07:48:21Zalexeymuranov (Alexey Muranov)
<ul></ul><p>=begin<br>
By the way, is anybody using the (({nil})) returned by (({#compact!})) ?</p>
<p>enum.map { |i| i + 1 if i.even? }.compact</p>
<p>makes un unnecessary copy, but i cannot use</p>
<p>enum.map { |i| i + 1 if i.even? }.compact!</p>
<p>because it will return (({nil})) if no changes were made.</p>
<p>Wouldn't it be better if (({#compact})) and (({#compact!})) returned the same thing?<br>
=end</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=273102012-06-20T07:23:14Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Em 19-06-2012 17:32, Roger Pack escreveu:</p>
<blockquote>
<blockquote>
<p>How about <code>#map_some</code> as the name?<br>
#map_if ?</p>
</blockquote>
</blockquote>
<p>I loved this one :)</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=288622012-08-14T18:24:26ZdrKreso (Kresimir Bojcic)kresimir.bojcic@gmail.com
<ul></ul><p>+1 I also like filter_map</p>
<p>(My other favourite would be map_selected which I think is more expressive for non-lisp-brainwashed)</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=288652012-08-14T20:25:35Ztrans (Thomas Sawyer)
<ul></ul><p>Instead of thinking of it as a special type of #map, I suggest thinking about it as a special type of #select. The reason is that we could also use the same type of behavior for #find. Which is why I suggest #select_yield and #find_yield (or #yield_select and #yield_find). The names of both of these need to be considered together.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=288682012-08-14T21:53:18ZAnonymous
<ul></ul><p>On Tue, Aug 14, 2012 at 1:25 PM, trans (Thomas Sawyer)<br>
<a href="mailto:transfire@gmail.com" class="email">transfire@gmail.com</a> wrote:</p>
<blockquote>
<p>Instead of thinking of it as a special type of #map, I suggest thinking about it as a special type of #select. The reason is that we could also use the same type of behavior for #find. Which is why I suggest #select_yield and #find_yield (or #yield_select and #yield_find). The names of both of these need to be considered together.</p>
</blockquote>
<p>To me it looks like a not-so-special type of inject.</p>
<p>How would map_select differ from inject, please?</p>
<p>Ciao,<br>
Sheldon.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=315522012-10-25T20:29:58Zyhara (Yutaka HARA)
<ul><li><strong>Target version</strong> changed from <i>2.0.0</i> to <i>2.6</i></li></ul> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=455952014-03-03T12:04:08Zshugo (Shugo Maeda)
<ul><li><strong>Status</strong> changed from <i>Feedback</i> to <i>Assigned</i></li></ul><p>Yukihiro Matsumoto wrote:</p>
<blockquote>
<p>I am OK with the original map_select behavior, but I don't like the name #map_select.<br>
It is combination of -ect family name with map.</p>
<p>I prefer the name #filter, but it might be confused by simple alias of select.<br>
Any idea?</p>
</blockquote>
<p>What do you think of the following counter proposals?</p>
<ul>
<li>select_yield</li>
<li>filter_map</li>
<li>map_if</li>
</ul> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=455972014-03-03T13:55:41Zsawa (Tsuyoshi Sawada)
<ul></ul><p>I would like to propose:</p>
<ul>
<li>partial_map</li>
</ul> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=456232014-03-04T13:52:41Zsawa (Tsuyoshi Sawada)
<ul></ul><p>Also, regarding Yehuda Katz's concern:</p>
<blockquote>
<p>The only caveat is that it would be impossible to intentionally return nil here; suggestions welcome.</p>
</blockquote>
<p>I would like to propose that the method takes an optional argument that determines what element is to be removed. By default, this is <code>nil</code>.</p>
<pre><code>[1, 2, 3, 4].partial_map{|i| i + 4 if i.even?} # => [6, 8]
s = "abc"
[0, 1, 2, 3, 4].partial_map(:ignore){|i| i.even? ? s[i] : :ignore} # => ["a", "c", nil]
</code></pre> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=458612014-03-18T18:27:17Zsawa (Tsuyoshi Sawada)
<ul></ul><p>I came to think that, if this feature is to be added, then are other methods to be considered: <code>flat_map</code> and <code>to_h</code> in addition to <code>map</code>. I think it should be either the case that the corresponding counterpart to all of these methods should be added, or none.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=461282014-04-09T14:41:53Zepidemian (Demian Ferreiro)epidemian@gmail.com
<ul></ul><p>I found this issue looking for a single-pass alternative to <code>.map{...}.compact</code>.</p>
<p>The former example uses <code>{ |i| i + 1 if i.even? }</code>, which reads almost like a comprehension and has a clear separation between the condition and the transformation. But sometimes it's not so easy to achieve such separation:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># Generate an array of integers from untrusted input.</span>
<span class="p">[</span><span class="s1">''</span><span class="p">,</span> <span class="s1">'42'</span><span class="p">,</span> <span class="s1">'nope'</span><span class="p">,</span> <span class="ss">:not_even_int_convertible</span><span class="p">].</span><span class="nf">compact_map</span> <span class="p">{</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="no">Integer</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">rescue</span> <span class="kp">nil</span> <span class="p">}</span> <span class="c1"># => [42]</span>
</code></pre>
<p>BTW, i think that <code>compact_map</code> sounds quite natural for what this method does, but it could also be an extension to <code>compact</code> as others have mentioned:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="s1">''</span><span class="p">,</span> <span class="s1">'42'</span><span class="p">,</span> <span class="s1">'nope'</span><span class="p">,</span> <span class="ss">:not_even_int_convertible</span><span class="p">].</span><span class="nf">compact</span> <span class="p">{</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="no">Integer</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">rescue</span> <span class="kp">nil</span> <span class="p">}</span> <span class="c1"># => [42]</span>
</code></pre>
<p>As long as this is considered an alternative to map + concat, i think it makes sense not to worry about the edge case of wanting to preserve the nils, as the purpose of compact is to wipe them out. For those cases a combination of <code>select</code> and <code>map</code> can be used, or <code>grep</code> with a proc as its "pattern" argument to avoid having two iterations.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=514662015-02-10T22:30:22Zrokob (Andrew Ledvina)wvvwwvw@gmail.com
<ul></ul><pre><code>The only caveat is that it would be impossible to intentionally return nil here
</code></pre>
<p>I don't see why you need that, just have the block return a pair <code>(keep_if_true, mapped_value)</code>. I also would second the name <code>filter_map</code>. Ignoring all edge-cases you could just do something like:</p>
<pre><code>module Array
def filter_map
result = []
self.each do |elem|
keep, value = yield elem
result << value if keep
end
result
end
end
> [1,32,9,33,2,13].filter_map{|v| [v < 20, v%2==1 ? v*2 : nil]]}
=> [2, 18, nil, 26]
</code></pre>
<p>Although to be fair, <code>filter_map</code> is just <code>reduce</code> with a more complicated block</p>
<pre><code>> [1,32,9,33,2,13].reduce([]){|acc, v| v<20 ? v%2==1 ? acc << v*2 : acc << nil : nil; acc}
=> [2, 18, nil, 26]
</code></pre> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=663702017-08-31T06:38:13Zshugo (Shugo Maeda)
<ul><li><strong>Related to</strong> <i><a class="issue tracker-2 status-5 priority-4 priority-default closed" href="/issues/13784">Feature #13784</a>: Add Enumerable#filter as an alias of Enumerable#select</i> added</li></ul> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=687352017-12-25T18:15:03Znaruse (Yui NARUSE)naruse@airemix.jp
<ul><li><strong>Target version</strong> deleted (<del><i>2.6</i></del>)</li></ul> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=767832019-02-13T02:35:50Zshugo (Shugo Maeda)
<ul><li><strong>Related to</strong> <i><a class="issue tracker-2 status-5 priority-4 priority-default closed" href="/issues/15323">Feature #15323</a>: [PATCH] Proposal: Add Enumerable#filter_map</i> added</li></ul> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=849212020-04-04T06:10:27Zsawa (Tsuyoshi Sawada)
<ul></ul><p>I think this proposal has been realized under the name <code>Enumerable#filter_map</code> following the duplicate proposal <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: [PATCH] Proposal: Add Enumerable#filter_map (Closed)" href="https://redmine.ruby-lang.org/issues/15323">#15323</a>. So it should be closed.</p> Ruby master - Feature #5663: Combined map/select methodhttps://redmine.ruby-lang.org/issues/5663?journal_id=849232020-04-04T06:46:00Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/84923/diff?detail_id=56781">diff</a>)</li><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li></ul>