This post originated from an RSS feed registered with Ruby Buzz
by Jan Lelis.
Original Post: New Array and Enumerable methods in Ruby 1.9.2
Feed Title: rbJ*_*L.net
Feed URL: http://feeds.feedburner.com/rbJL
Feed Description: Hi, I am a fan of Ruby and like to explore it and the world around ;).
So I started this blog, where I am publishing code snippets, tutorials for beginners as well as general thoughts about Ruby, the web or programming in general.
In Ruby, dealing with Arrays and similar objects is pretty fun. And we have gotten more possibilities with Ruby 1.9.2 :)
The NEWS file says:
* Array
* new method:
* Array#keep_if
* Array#repeated_combination
* Array#repeated_permutation
* Array#rotate
* Array#rotate!
* Array#select!
* Array#sort_by!
* extended methods:
* Array#{uniq,uniq!,product} can take a block.
...
* Enumerable
* New methods:
* Enumerable#chunk
* Enumerable#collect_concat
* Enumerable#each_entry
* Enumerable#flat_map
* Enumerable#slice_before
Let’s take a closer look!
select! and keep_if
The select method (only choose the elements for which the block evaluates to true) got a mutator version select!. It does almost the same like the new keep_if method – with one subtle difference: select! returns nil if no changes were made, keep_if always returns the object.
more combination and permutation
Ruby 1.9 introduced the useful methods combination and permutation. Now there are also repeated_combination and repeated_permutation:
This method removes the first element and appends it. You can pass an integer, how many steps it should “cycle” (negative values are possible). It does something like:
This method works like map, but if an element is an Enumerable itself, the applied block is also run for each of its child elements (but not recursively).
I do not know (yet), if this is useful (and if it wouldn’t be cooler if it did something like .flatten.map), but we will see…
each_entry
Each entry is like each, but it treats multiple yield arguments as a single array (so yield 1,2 implicitly becomes yield [1,2]). Mostly, the result is similar to eachs, but there are some occasions where it does matter.
chunk
This one is interesting, but it is a little bit strange to use. It splits self into multiple Enumerators, using the rule given in the block. It keeps together those parts that “match” in series. It passes the result of the “filter” rule and an Enumerator of the successive elements – Look at these two examples:
%w|Ruby is 2 parts Perl, 1 part Python, and 1 part Smalltalk|.slice_before(/\d/).to_a#=> [["Ruby", "is"], ["2", "parts", "Perl,"], ["1", "part", "Python,", "and"], ["1", "part", "Smalltalk"]]# a more complex version from the docs (slightly modified):a=[0,2,3,4,6,7,9]prev=a[0]a.slice_before{|cur|prev,prev2=cur,prev# one step furtherprev2+1!=prev# two ago != one ago ? --> new slice}.to_a# => [[0], [2, 3, 4], [6, 7], [9]]
What’s next?
It is quite interesting to observe, in which direction Ruby moves with this methods. Some of them where just “missing” previously (e.g. select!). However, some others seem to be for a very special purpose only (chunk) – but maybe it is just a false interpretation on the face of it ;)