Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby, how to shuffle one array into another

Two arrays:

a1 = ["a", "b", "c", "d", "e", "f"]
a2 = [1, 2, 3]

How to insert a2 into a1, keeping the a2 order but in random indexes of a1?

like image 304
fguillen Avatar asked May 16 '26 00:05

fguillen


2 Answers

(0..a1.length).to_a.sample(a2.length).sort
.zip(a2)
.reverse
.each{|i, e| a1.insert(i, e)}
like image 90
sawa Avatar answered May 18 '26 18:05

sawa


Here's my updated answer:

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"]

Credit for the algorithm goes to my colleague Ryan.

OLD ANSWER DOES NOT PRESERVE ORDER OF BOTH

a1.inject(a2) { |s,i| s.insert(rand(s.size), i) }

Using a2 as a destination, insert into a2 each value from a1 at a random offset of a2.

like image 40
bheeshmar Avatar answered May 18 '26 20:05

bheeshmar