Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

DZone's Guide to

Partitioning An Array With Array#collect_every And Array#subdivide

·
Free Resource

Comment (0)

Save
{{ articles[0].views | formatCount}} Views
```Array#collect_every is taken from:

http://redhanded.hobix.com/bits/matchingIntoMultipleAssignment.html

Author: Ezra Zygmuntowicz (in the comments)

```

# ---------------------------------------------------------------------------
# collect_every(n [,fill=false[,offset=0]])                  => an array
# collect_every(n [,fill=false[,offset=0]]) {|item| block}   => an_array
# ---------------------------------------------------------------------------
# If a block is given, it invokes the block passing in an array of n elements.
# The last array passed may not contain n elements if size % 2 does not equal
# zero. If no block is given, it returns an array containing the collections.
#
# If the optional argument fill is set to true, the empty spaces will be
# filled with nils. The optional argument offset allows the collection to
# start at that index in the array.
#
# a = (1..10).to_a
# a.collect_every(5)               #=> [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
# a.collect_every(5) {|x| p x}     #=> [1, 2, 3, 4, 5]
#                                      [6, 7, 8, 9, 10]
# b = (1..7).to_a
# b.collect_every(3)               #=> [[1, 2, 3], [4, 5, 6], [7]]
# b.collect_every(3,true)          #=> [[1, 2, 3], [4, 5, 6], [7,nil,nil]]
# b.collect_every(3,true,1)        #=> [[2, 3, 4], [5, 6, 7]]

class Array

def collect_every(n, fill=false, offset = 0)

if block_given?
while  offset < size
ret = []

if fill
n.times do |x|
if offset + x > size - 1 then ret << nil
else  ret << self[offset + x] end
end
else
n.times { |x| ret << self[offset + x] unless offset + x > size - 1}
end

offset += n
yield ret
ret = nil
end

else

ret = []
while  offset < size
ret << []
if fill
n.times do |x|
if offset + x > size - 1 then ret.last << nil
else ret.last << self[offset + x]; end
end
else
n.times { |x| ret.last << self[offset + x] unless offset + x > size - 1 }
end

offset += n
end
return ret

end

end
end

a = (1..10).to_a
puts a.collect_every(5).inspect                     #->  [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
a.collect_every(5) { |x| puts x.inspect }         #->  [1, 2, 3, 4, 5] and [6, 7, 8, 9, 10]
puts a.collect_every(3, true).inspect             #->  [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, nil, nil]]
puts a.collect_every(3, true,1).inspect          #->  [[2, 3, 4], [5, 6, 7], [8, 9, 10]]
puts a.collect_every(3, true,4).inspect          #->  [[5, 6, 7], [8, 9, 10]]

puts a.inspect                                              #->  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# ------------------------------------------------------------------------

class Array

def subdivide(n)
return self if n <= 0 || n >= self.size
result = []
max_subarray_size = n - 1

while self.size > 0
result << self.slice!(0..max_subarray_size)
end

result
end

end

a = ('a'..'g').to_a
b = a.subdivide(3)

puts b.inspect       #->  [["a", "b", "c"], ["d", "e", "f"], ["g"]]
puts a.inspect       #->  []

``````
Topics:

Comment (0)

Save
{{ articles[0].views | formatCount}} Views

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}