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 :

repeated_combination_permutation 1 2 3 4 5 6 7 8 >> [ 1 , 2 , 3 ]. combination ( 2 ). to_a => [[ 1 , 2 ], [ 1 , 3 ], [ 2 , 3 ]] >> [ 1 , 2 , 3 ]. repeated_combination ( 2 ). to_a => [[ 1 , 1 ], [ 1 , 2 ], [ 1 , 3 ], [ 2 , 2 ], [ 2 , 3 ], [ 3 , 3 ]] >> [ 1 , 2 , 3 ]. permutation ( 2 ). to_a => [[ 1 , 2 ], [ 1 , 3 ], [ 2 , 1 ], [ 2 , 3 ], [ 3 , 1 ], [ 3 , 2 ]] >> [ 1 , 2 , 3 ]. repeated_permutation ( 2 ). to_a => [[ 1 , 1 ], [ 1 , 2 ], [ 1 , 3 ], [ 2 , 1 ], [ 2 , 2 ], [ 2 , 3 ], [ 3 , 1 ], [ 3 , 2 ], [ 3 , 3 ]]

rotate / rotate!

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:

rotate 1 2 3 4 5 6 class Array def rotate2 ( n = 1 ) new_start = n % self . size self [ new_start ..- 1 ] + self [ 0 ... new_start ] end end

small changes: sort_by , uniq / uniq! , product

sort_by (the block defines, how the Array should be sorted) also got a mutator version: sort_by! .

(the block defines, how the Array should be sorted) also got a mutator version: . product (combine all elements from both Arrays) now also accepts a block which yields every result, instead of returning it.

(combine all elements from both Arrays) now also accepts a block which yields every result, instead of returning it. uniq (remove duplicates) can now take a block, example from the docs:

uniq_block 1 2 c = [ " a:def ", " a:xyz ", " b:abc ", " b:xyz ", " c:jkl " ] c . uniq {| s | s [/ ^ \w + /]}

flat_map and its alias collect_concat

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).

flat_map 1 [[ 1 , 2 ],[ 3 ,[ 4 , 5 ]]]. flat_map {| i | i }

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 each ’s, 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:

chunk 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ( 1 .. 42 ). chunk {| n | n % 11 == 0 }. each {| result , elements | puts " #{result} : #{elements*' - '} " } a =( 0 .. 4 ). map {[]} ( 1 .. 42 ). chunk {| n | n % 5 }. each {| remainder , elements | a [ remainder ] += elements } p a

The chunk block can also return some special values: Symbols that begin with an underscore. Currently, there are two special symbols supported:

:_separator (or nil ) – the element is dropped

(or ) – the element is dropped :_alone – the element always gets its single chunk

Some advanced examples can be found in the docs.

slice_before

This method also lets you split the Enumerable. You simply specify a pattern/a block which has to match/be true and it splits before that element:

slice_before 1 2 3 4 5 6 7 8 9 10 11 %w| Ruby is 2 parts Perl, 1 part Python, and 1 part Smalltalk |. slice_before (/ \d /). to_a a = [ 0 , 2 , 3 , 4 , 6 , 7 , 9 ] prev = a [ 0 ] a . slice_before {| cur | prev , prev2 = cur , prev prev2 + 1 != prev }. to_a

What’s next?