Issue #13784 has been updated by davidarnold (David Arnold).


> On another note, there is a small difference between 'find_all' and 'select', due to 'select' being overridden for hashes. (https://stackoverflow.com/questions/20999192/is-find-all-and-select-the-same-thing)
> It might be inconsequential, but the 'filter' method in my pull request acts more like 'find_all'.

This is a very interesting find, I was very surprised that select and find_all currently do not work the same way in Hash.  I did some archeology on the commits and I believe this is an unintentional oversight.

Enumerable#select was added in 1999 for Ruby 1.4.0 as an alias for Enumerable#find_all, which already existed.  Hash was an Enumerable, so it would have gotten these methods too.

Then in 2001, between Ruby 1.6.x and 1.8.0, Hash#select was overridden presumably to support a hash.select(key1, key2, ...) syntax for returning multiple values.  If a block was passed, it still worked like Hash#find_all.  Interestingly enough, this feature was deprecated in 2003 before 1.8's release.

Later in 2003, the deprecated non-block code path in Hash#select was removed for the release of 1.8.2.  After this change, Hash#select would have worked like Enumerable#select again, making the override appears superfluous to me.

Much later in 2007, Hash#select was changed to its present form, returning a hash instead of an array, leaving Hash#find_all with the Enumerable implementation that still returns an array.  This change was included for the release of Ruby 1.9.

So my guess is that only Hash#select got the new behavior since it already existed in hash.c whereas find_all was only defined in Enumerable.  Assuming this feature is approved, I will open a separate bug to start a discussion about whether the discrepancy is intentional or if Hash#find_all should be changed to match Hash#select.

For the purpose of this feature request, I would leave the filter == find_all behavior the same.  If the decision in the bug report is that Hash#find_all should match Hash#select, then an alias can be added for both Hash#find_all and Hash#filter.
 

----------------------------------------
Feature #13784: Add Enumerable#filter as an alias of Enumerable#select
https://bugs.ruby-lang.org/issues/13784#change-66075

* Author: davidarnold (David Arnold)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Ruby has a full set of functional tools in the Enumerable module under the "-ect" methods (viz. collect, select, inject).  However the usual industry terms for these are map, filter, and reduce.

For example, Swift, Python, and ECMAScript all use the names map, filter, and reduce to describe these methods.  Also, this language independent MIT course uses map, filter and reduce: http://web.mit.edu/6.005/www/fa15/classes/25-map-filter-reduce/

Ruby has aliases for map and reduce, but filter is noticeably absent.  This feature request is simply to add an alias to Enumerable for filter.  This will ease the transition of developers from other languages to Ruby.

Desired behavior:

[:foo, :bar].filter { |x| x == :foo } # => [:foo]

Current behavior:

[:foo, :bar].filter { |x| x == :foo } # NoMethodError: undefined method `filter'



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>