Enumerable#filter

01 04 2009

Update: Thanks to some feedback I rewrote Enumberable#filter so it doesn’t use ‘eval’. It’s a bit less flexible now and I also like the syntax less, but at least it doesn’t eat puppies for breakfast. As the disclaimer said, maybe it was a bad idea to begin with.

As much as I like Ruby, some constructs I just don’t find too sexy, e.g.:

[1,2,5,8,7,3,1,9,5].select { |x| x < 5 }

That’s why I came up with an alternative solution which I find reads nicer than the above code:


(Sorry, I really don’t care much about having this for strings)

I kinda got inspired by Martin Aumont’s every, which allows us to use

enum.every.floor

instead of

enum.map {|n| n.floor }
# or in 1.8.7 or 1.9.1
enum.map(&:floor)  

Disclaimer: Today this seems like a pretty good idea, but I also haven’t slept much. In case this breaks in horrible ways, already exists in some other form or is stupid for some other reason I’m too tired to consider, please let me know.



Trackbacks


06 04 2009
FilterableEnumerable
My recent post on Enumerable#filter created a bit of &#8220;discussion&#8221;: on RubyFlow, which led to a much nicer implementation than mine which can be found here. Enjoy!
Weblog: citizen428.blog()
Tracked: Apr 06, 00:33

Comments

Display comments as (Linear | Threaded)
02 04 2009
#1 Patrick Schless (Reply)

Interesting idea. You could make it work with strings by changing #{el} to #{el.inspect}, though String#select is line-based, not character-based, so it may not be quite what you’re looking for.

The problem with eval (one of them, anyway), is performance. A quick test shows #filter to be about ten times slower than #select. Still, an interesting addition to the enumerable family :-)

02 04 2009
#1.1 Michael Kohl (Reply)

Since – as you said – String#each (and therefore also String#select) is line-based, I didn’t care much about it.

I did a quick speed test too, and although #filter seems to be a bit slower, it’s not ten times slower. What concerns me more right now is the possibility to do

test.filter(">3; system(‘touch foo’)")

Quite a show-stopper really.

19 07 2009
#2 trans (Reply)

FYI, Martin Aumont’s every, is actually Trans’ every. It’s been in Ruby Facets for years.

24 08 2009
#2.1 citizen428 (Reply)

Sorry, I wasn’t aware of the fact that "every" also is part of Facets, my apologies!


Add Comment


Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Textile-formatting allowed

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA 1CAPTCHA 2CAPTCHA 3CAPTCHA 4CAPTCHA 5


Standard emoticons like :-) and ;-) are converted to images.