平均而言,每隔五个项目设置为true,但不是按顺序设置

时间:2014-11-25 18:03:29

标签: ruby

我有一个包含100个项目的集合。

在迭代中,我想在20%的项目上将对象属性设置为true

但我不希望设置为均匀,即每五个项目。

如果不完全20%获得true,只要设置不均匀,就可以了。

4 个答案:

答案 0 :(得分:3)

实现这一目标的低效但简洁的方法是对数组进行洗牌,对前20个元素进行切片,然后在其上设置属性。

items.shuffle[0..19].each do |item|
  item.foo = true
end

如果您关心效率,可能需要考虑修改Fisher Yates算法。

答案 1 :(得分:1)

您可以使用rand

def true_20_percent_of_the_time
  rand(5) == 0
end

答案 2 :(得分:1)

如果您正在生成数组:

ary = Array.new(2, true) + Array.new(8, false)
ary # => [true, true, false, false, false, false, false, false, false, false]
ary.shuffle # => [false, false, true, false, false, false, false, false, false, true]

仅使用10个元素作为示例,但我相信您可以弄清楚如何调整计数。

以上可以简化为:

ary = (Array.new(2, true) + Array.new(8, false)).shuffle
# => [false, false, true, false, true, false, false, false, false, false]

这可以简化为:

ary = (([true] * 2) + ([false] * 8)).shuffle
# => [false, false, false, true, false, false, true, false, false, false]

如果它是预先存在的数组:

ARRAY_SIZE = 10
ary = [false] * ARRAY_SIZE

然后您可以对其进行切片并重新分配所需的true元素数量:

ary[0, (ARRAY_SIZE * 0.20).to_i] = [true] * (ARRAY_SIZE * 0.20)
ary # => [true, true, false, false, false, false, false, false, false, false]

然后shuffle

ary.shuffle # => [true, false, false, false, false, false, false, false, false, true]

答案 3 :(得分:0)

让我们说你有阵列

a = Array.new(21) { |i| i }
  #=> [0, 1, 2, 3,..., 19, 20]

你想要选择

(a.size/5.0).round #=> 4

随机元素。然后你可以写:

@lucky_ones = [*(0...a.size)].sample((a.size/5.0).round)
  #=> [6, 12, 3, 9]

a.each_with_index do |e,i|
  puts "Wow! I've been selected. I'm #{e}" if @lucky_ones.include? i
end

Wow! I've been selected. I'm 3
Wow! I've been selected. I'm 6
Wow! I've been selected. I'm 9
Wow! I've been selected. I'm 12