Ruby 2.7 adds a couple of new methods to Enumerable:
Enumerable#filter_map. For example: (1..10).filter_map { |i| i * 2 if i.even? } # => [4, 8, 12, 16, 20]. This is useful to avoid having to do .select { ... }.map { ... } which creates an intermediate array and it’s a very common idiom in functional languages (like Haskell and Elm).
Enumerable#tally. For example ['a', 'b', 'a', 'b', 'b'].tally # => {'a' => 2, 'b' => 3}. Counting things is pretty common, I think.
Should we add these to Crystal? They seem easy to implement and generally useful.
tally is nice, i’ve even used such function few times.
But I have to say that (as non-native speaker) never heard this word so would never guess this name. Maybe it’s just me.
I agree. The same happened to me too. I think Ruby chose that name because chances of it colliding with a user-defined method named like that is very unlikely.
tally seems like a fine name to me, as an american (although I suspect it’s more widely used in England than the USA). As soon as I saw the method name, I knew what it was going to do.
On the other hand, it does seem to be true that I’ve never thought to use it in any program I’ve written, even though I have quite a few programs which have tallied things up like that!
Speaking of which, twould be nice to have the “lazy eval” type chaining so that no intermediate arrays are required [wait does that actually speed up things though? LOL]. And, following on after that, the java style “parallel stream” chains. Do those speed things up? Also don’t know…
Technically you can use compact_map to do what filter_map does by just doing like next unless condition. The nil values will be filtered out so you end up with a filtered array from only a single iteration of the source collection.
Use Ruby or Crystal, prefer write clean code, filter_map is more clear than compact_map when do same thing.
in fact, both of them not same, compact_map only can do part of filter_map thing, we really should add filter_map instead of compact_map (or both), because the former is the superset of latter.
Not saying we shouldn’t add it, just that compact_map can work as a more efficient version of .select { }.map { } until if/when filter_map is a thing. This is really the first we’re hearing of a use case for it, so must not have been all that desired until now.