Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: rework_initial…
117 lines (108 sloc) 3.292 kb
class Array
# Splits or iterates over the array in groups of size +number+,
# padding any remaining slots with +fill_with+ unless it is +false+.
#
# %w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3) {|group| p group}
# ["1", "2", "3"]
# ["4", "5", "6"]
# ["7", "8", "9"]
# ["10", nil, nil]
#
# %w(1 2 3 4 5).in_groups_of(2, ' ') {|group| p group}
# ["1", "2"]
# ["3", "4"]
# ["5", " "]
#
# %w(1 2 3 4 5).in_groups_of(2, false) {|group| p group}
# ["1", "2"]
# ["3", "4"]
# ["5"]
def in_groups_of(number, fill_with = nil)
if number.to_i <= 0
raise ArgumentError,
"Group size must be a positive integer, was #{number.inspect}"
end
if fill_with == false
collection = self
else
# size % number gives how many extra we have;
# subtracting from number gives how many to add;
# modulo number ensures we don't add group of just fill.
padding = (number - size % number) % number
collection = dup.concat(Array.new(padding, fill_with))
end
if block_given?
collection.each_slice(number) { |slice| yield(slice) }
else
collection.each_slice(number).to_a
end
end
# Splits or iterates over the array in +number+ of groups, padding any
# remaining slots with +fill_with+ unless it is +false+.
#
# %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group}
# ["1", "2", "3", "4"]
# ["5", "6", "7", nil]
# ["8", "9", "10", nil]
#
# %w(1 2 3 4 5 6 7 8 9 10).in_groups(3, '&nbsp;') {|group| p group}
# ["1", "2", "3", "4"]
# ["5", "6", "7", "&nbsp;"]
# ["8", "9", "10", "&nbsp;"]
#
# %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
# ["1", "2", "3"]
# ["4", "5"]
# ["6", "7"]
def in_groups(number, fill_with = nil)
# size.div number gives minor group size;
# size % number gives how many objects need extra accommodation;
# each group hold either division or division + 1 items.
division = size.div number
modulo = size % number
# create a new array avoiding dup
groups = []
start = 0
number.times do |index|
length = division + (modulo > 0 && modulo > index ? 1 : 0)
groups << last_group = slice(start, length)
last_group << fill_with if fill_with != false &&
modulo > 0 && length == division
start += length
end
if block_given?
groups.each { |g| yield(g) }
else
groups
end
end
# Divides the array into one or more subarrays based on a delimiting +value+
# or the result of an optional block.
#
# [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
# (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
def split(value = nil)
if block_given?
inject([[]]) do |results, element|
if yield(element)
results << []
else
results.last << element
end
results
end
else
results, arr = [[]], self.dup
until arr.empty?
if (idx = arr.index(value))
results.last.concat(arr.shift(idx))
arr.shift
results << []
else
results.last.concat(arr.shift(arr.size))
end
end
results
end
end
end
Jump to Line
Something went wrong with that request. Please try again.