Suppose I have:
a = [['a', 'b', 'c', 'd', 'e'], ['f', 'g', 'h'], ['i', 'j'], ['k']]
And from that, I want to join pairs but leave a remainder element unchanged like so:
[["a_b", "c_d", "e"], ["f_g", "h"], ["i_j"], ["k"]]
Closest I have (that produces the result) is:
r = a.map { |sl|
tmp = []
sl.each_slice(2) { |a, b| tmp << (b.nil? ? a : "#{a}_#{b}") }
tmp
}
Alternatively:
r = a.map { |sl|
tmp = []
sl.each_slice(2) { |a, b| tmp << (b.nil? ? a : [a,b].join("_")) }
tmp
}
Is there a cleaner way to do this?
CodePudding user response:
Is there a cleaner way to do this?
each_slice
returns anEnumerator
if no block is given.Enumerator
responds tomap
map
will yield the full "sliced" sub array to the blockeach_slice
does not guarantee ann
element array. If the slice is uneven then it will just yield what is left.
Knowing all of this your implementation can be simplified to:
a.map { |s1| s1.each_slice(2).map { |e| e.join("_") } }