如何将数组中的前n个元素混洗

时间:2018-06-05 07:17:12

标签: arrays ruby

让:

example = [1,2,3,4,5,6,7,8,9]

我想改组它的前五个元素。其他元素必须保持在相同的索引下,例如:

[2,4,1,3,5,6,7,8,9]
[3,1,4,5,2,6,7,8,9]
# etc

我尝试了example.shuffle,但它会改变所有元素。

5 个答案:

答案 0 :(得分:10)

您可以通过[] 获取前5个元素:

example[0, 5]
#=> [1, 2, 3, 4, 5]

同样,你可以通过[]= 设置前5个元素:

example[0, 5] = [5, 4, 3, 2, 1]
#=> [5, 4, 3, 2, 1]

example
#=> [5, 4, 3, 2, 1, 6, 7, 8, 9]

所以对shuffle前5个元素,你可以使用:

example[0, 5] = example[0, 5].shuffle
#=> [3, 2, 1, 4, 5]

example
#=> [3, 2, 1, 4, 5, 6, 7, 8, 9]

请注意,example[0, 5].shuffle! 可以正常工作,因为Array#[]会返回一个新数组而不是对子数组的引用(Ruby中没有这样的东西)。

答案 1 :(得分:2)

a = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
a[0..4].shuffle + a[5..-1]

答案 2 :(得分:2)

example = [1, 2, 3, 4, 5, 6, 7, 8, 9]

example.first(5).shuffle + example.last(4)

将返回您需要的数组,尽管它可能不是最优雅的解决方案

修改

正如@Stefan评论的那样,您可以使用drop,因此您无需计算剩余数组的长度:

example.first(5).shuffle + example.drop(5)

答案 3 :(得分:1)

一些更有趣的方式:(所有非破坏性的)

 a =[*1..9]

 a.each_slice(5).to_a.tap do |f| 
   f.first.shuffle!
 end.reduce(:+)

 a.reduce([]) do |memo,n|
   (memo << n).size == 5 ? memo.shuffle : memo
 end

 a.partition.with_index do |_,i| 
   i < 5 
 end.inject { |memo,p| memo.shuffle.concat(p) }

 a.values_at(*[*0..4].shuffle).push(*a.drop(5)) 

我也非常喜欢这个,但只有所有元素都保证唯一

 a.take(5).shuffle | a

答案 4 :(得分:0)

我迟到了,但是我的两分钱。 这是破坏性的。

example.shift(5).shuffle + example