Upgraded Rails and RSpec
[monkeycharger.git] / vendor / rails / activesupport / lib / active_support / core_ext / array / grouping.rb
blob52ed61d3dc7d55b6634280a544d0fd5ddd993f8a
1 require 'enumerator'
3 module ActiveSupport #:nodoc:
4   module CoreExtensions #:nodoc:
5     module Array #:nodoc:
6       module Grouping
7         # Iterate over an array in groups of a certain size, padding any remaining 
8         # slots with specified value (<tt>nil</tt> by default) unless it is
9         # <tt>false</tt>.
10         # 
11         # E.g.
12         # 
13         #   %w(1 2 3 4 5 6 7).in_groups_of(3) {|g| p g}
14         #   ["1", "2", "3"]
15         #   ["4", "5", "6"]
16         #   ["7", nil, nil]
17         #
18         #   %w(1 2 3).in_groups_of(2, '&nbsp;') {|g| p g}
19         #   ["1", "2"]
20         #   ["3", "&nbsp;"]
21         #
22         #   %w(1 2 3).in_groups_of(2, false) {|g| p g}
23         #   ["1", "2"]
24         #   ["3"]
25         def in_groups_of(number, fill_with = nil, &block)
26           if fill_with == false
27             collection = self
28           else
29             # size % number gives how many extra we have;
30             # subtracting from number gives how many to add;
31             # modulo number ensures we don't add group of just fill.
32             padding = (number - size % number) % number
33             collection = dup.concat([fill_with] * padding)
34           end
36           if block_given?
37             collection.each_slice(number, &block)
38           else
39             returning [] do |groups|
40               collection.each_slice(number) { |group| groups << group }
41             end
42           end
43         end
45         # Divide the array into one or more subarrays based on a delimiting +value+
46         # or the result of an optional block.
47         #
48         # ex.
49         #
50         #   [1, 2, 3, 4, 5].split(3)                # => [[1, 2], [4, 5]]
51         #   (1..10).to_a.split { |i| i % 3 == 0 }   # => [[1, 2], [4, 5], [7, 8], [10]]
52         def split(value = nil, &block)
53           block ||= Proc.new { |e| e == value }
55           inject([[]]) do |results, element|
56             if block.call(element)
57               results << []
58             else
59               results.last << element
60             end
62             results
63           end
64         end
65       end
66     end
67   end
68 end