两个阵列:
a1 = ["a", "b", "c", "d", "e", "f"]
a2 = [1, 2, 3]
如何将a2
插入a1
,保留 a2订单但 a1 的随机索引?
答案 0 :(得分:6)
(0..a1.length).to_a.sample(a2.length).sort
.zip(a2)
.reverse
.each{|i, e| a1.insert(i, e)}
答案 1 :(得分:5)
这是我更新的答案:
a1 = ["a", "b", "c", "d", "e", "f"]
a2 = [1,2,3]
# scales to N arrays by just adding to this hash
h = { :a1 => a1.dup, :a2 => a2.dup }
# => {:a1=>["a", "b", "c", "d", "e", "f"], :a2=>[1, 2, 3]}
# Create an array of size a1+a2 with elements representing which array to pull from
sources = h.inject([]) { |s,(k,v)| s += [k] * v.size }
# => [:a1, :a1, :a1, :a1, :a1, :a1, :a2, :a2, :a2]
# Pull from the array indicated by the hash after shuffling the source list
sources.shuffle.map { |a| h[a].shift }
# => ["a", "b", 1, "c", 2, "d", "e", 3, "f"]
算法归功于我的同事瑞安。
老答案没有保留两种顺序
a1.inject(a2) { |s,i| s.insert(rand(s.size), i) }
使用a2作为目的地,将a1中的每个值插入a2,随机偏移量为a2。
答案 2 :(得分:3)
通过模拟真实的混洗来维持两个数组的顺序,一旦数组的元素插入到另一个数组中,下一个元素就不能放在它之前。
class Array
def shuffle_into(array)
n = 0
self.each.with_object(array.dup) do |e, obj|
i = rand(n..obj.size)
obj.insert(i, e)
n = i + 1
end
end
end
可能能够清理漂浮在周围的n = 0
。
示例:a2.shuffle_into(a1) => [1, "a", "b", "c", "d", 2, "e", "f", 3]
答案 3 :(得分:2)
这个丑陋的垃圾完成了这项工作(没有搞乱任何数组顺序):
class Array
def shuffle_into(ary)
a1 = ary.dup
a2 = dup
Array.new(a1.size + a2.size) do
[true, false].sample ? (a1.shift || a2.shift) : (a2.shift || a1.shift)
end
end
end
答案 4 :(得分:-1)
a1.zip((a2 + [nil] * (a1.size - a2.size)).shuffle).flatten.compact
BTW,可能是dup:Zipping 2 arrays in ruby in random locations