Ruby,同样分配元素并交错/合并多个数组

时间:2013-03-26 03:35:41

标签: ruby arrays merge distribute

我有多个未知元素数的数组,如

a = []
a << [:a, :c, :e]
a << [:b, :f, :g, :h, :i, :j]
a << [:d]

结果应该是〜(我不关心细节因为舍入等)

r = [:b, :a, :f, :g, :d, :c, :h, :i, :e, :j]

这就是我认为可以做到的方式

首先,我们需要在每个数组中扩展/分发同等元素到相同的长度,所以我们得到像

a << [nil, :a, nil, :c, nil, :e]
a << [:b, :f, :g, :h, :i, :j]
a << [nil, nil, :d, nil, nil]

接下来,我们交错,就像通常那样

r = a.shift
a.each { |e| r = r.zip(e) }
r = r.flatten.compact

我目前的问题是如何在数组中平均分配这些元素(尽可能多)?可能有一个数组包含4个元素,另一个数组包含5个元素,但最重要的可能是第一个。

当然很高兴看到是否有其他方法可以实现这一点:)

1 个答案:

答案 0 :(得分:2)

我会使用排序来做这个,基于元素索引位置,除以数组的大小,加上一些基于数组id的偏移量,以保持一致(如果你不需要一致性,你可以使用一个小的而是随机偏移)。

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 all the arrays with their sort index, assigning ids to each array for consistency.
# Depending on how you receive these arrays, this structure can be built up programatically, 
# as long as you add an array plus its sort index numbers at the 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 the values from the original arrays in their new order
combined.sort_by { |zipped| zipped[1] }.map { |zipped| zipped[0] }

=> [:g, :d, :a, :h, :e, :i, :b, :f, :j, :c]

在Ruby中可能有更简洁的方法。 。 。但我认为最终结果就是你所追求的 - 多个阵列的“均匀”组合。

如果你只是从统计角度关注混合的均匀性(即随着时间的推移它是“公平的”),你可以这样做:

(a+b+c+d).shuffle

=> [:g, :b, :i, :c, :a, :h, :e, :j, :f, :d]