arr = [["a", "b", "c"], ["a", "b"], ["a", "b", "c"], ["a", "c"],
["c", "v"], ["c", "f"], ["e", "a"], ["a", "b", "v"],
["a", "n", "c"], ["a", "b", "m"], ["a", "c"], ["a", "c", "g"]]
arr.each_with_object([[]]) do |a,ar|
if a.size + ar[-1].size > 6
ar << a
else
ar[-1] += a
end
end
#=> [["a", "b", "c", "a", "b"], ["a", "b", "c", "a", "c"],
# ["c", "v", "c", "f", "e", "a"], ["a", "b", "v", "a", "n", "c"],
# ["a", "b", "m", "a", "c"], ["a", "c", "g"]]
The steps are as follows.
enum = arr.each_with_object([[]])
#=> #<Enumerator: [["a", "b", "c", "a", "b"], ["a", "b"],...
# ["a", "c", "g"]]:each_with_object([[]])>
The first value is generated by this enumerator, passed to the block and the block values are assigned values by applying Array Decomposition to the two-element array passed to the block.
a, ar = enum.next
#=> [["a", "b", "c"], [[]]]
a #=> ["a", "b", "c"]
ar #=> [[]]
See Enumerator#next. The conditional statement is then evaluated.
a.size + ar[-1].size > 6
#=> 3 + 0 > 6 => false
so we execute:
ar[-1] += a
#=> ["a", "b", "c"]
ar #=> [["a", "b", "c"]]
The next element is generated by enum
, passed to the block and the block values are assigned values.
a, ar = enum.next
#=> [["a", "b"], [["a", "b", "c"]]]
a #=> ["a", "b"]
ar #=> [["a", "b", "c"]]
The conditional statement is evaluated.
a.size + ar[-1].size > 6
#=> 2 + 3 > 6 => false
so again we execute:
ar[-1] += a
#=> ["a", "b", "c", "a", "b"]
ar #=> [["a", "b", "c", "a", "b"]]
enum
then passes the third element to the block.
a, ar = enum.next
#=> [["a", "b", "c"], [["a", "b", "c", "a", "b"]]]
a #=> ["a", "b", "c"]
ar #=> [["a", "b", "c", "a", "b"]]
Because:
a.size + ar[-1].size > 6
#=> 3 + 5 > 6 => false
this time we exectute
ar << a
#=> [["a", "b", "c", "a", "b"], ["a", "b", "c"]]
The remaining steps are similar.
stop
variable only grows up (and the third element makes it exceed 6). – Sergio Tulentsev