Ruby, equally distribute elements and interleave/merge multiple arrays -
i have multiple arrays unknown element count like
a = [] << [:a, :c, :e] << [:b, :f, :g, :h, :i, :j] << [:d]
result should ~ (i don't care details due rounding etc)
r = [:b, :a, :f, :g, :d, :c, :h, :i, :e, :j]
this how think done
first need expand/distribute equally elements in each array same length,
a << [nil, :a, nil, :c, nil, :e] << [:b, :f, :g, :h, :i, :j] << [nil, nil, :d, nil, nil]
next interleave them typically
r = a.shift a.each { |e| r = r.zip(e) } r = r.flatten.compact
my current problem how equally (as it's possible) distribute elements across array? there 1 array 4 elements , other 5, biggest should go first.
of course nice see if there's other way achieve :)
i use sort this, based on element index postion, divided size of array, plus offset based on array id, keep things consistent (if don't need consistency, use small random offset instead).
a = [:a,:b] b = [:c] c = [:d,:e,:f] d = [:g:,:h,:i,:j] def sort_pos array, id (1..array.size).map { |i| (i - 0.5 + id/1000.0)/(array.size + 1e-6) } end # combine arrays sort index, assigning ids each array consistency. # depending on how receive these arrays, structure can built programatically, # long add array plus sort index numbers @ same time combined = (a + b + c + d).zip( sort_pos(a, 1) + sort_pos(b, 2) + sort_pos(c, 3) + sort_pos(d, 4) ) # extract values original arrays in new order combined.sort_by { |zipped| zipped[1] }.map { |zipped| zipped[0] } => [:g, :d, :a, :h, :e, :i, :b, :f, :j, :c]
there might cleaner way of doing in ruby . . . think end result after - "even" mix of multiple arrays.
if care even-ness of mix statistical perspective (i.e. on time "fair"), this:
(a+b+c+d).shuffle => [:g, :b, :i, :c, :a, :h, :e, :j, :f, :d]
Comments
Post a Comment