从数组1中挑选最多的项目,从数组2中获取更少的项目等

时间:2015-02-28 19:55:00

标签: ruby

如何根据它们的“重要性”随机无限地循环遍历这些数组中的对象?

test = [
  important = [
    "lorem",
    "ipsum"
  ],
  kinda_important = [
    "dolor",
    "sit"
  ],
  not_so_important = [
    "amet",
    "consectetur"
  ]
]

test.shuffle.each do |test|
  sleep 5
  puts test 
end

应输出ie。:

lorem
lorem
sit
ipsum
lorem
ipsum
ipsum
dolor
ipsum
sit
amet
lorem
ipsum
dolor
lorem
sit
...

最常输出importantkinda_important更少等等。

3 个答案:

答案 0 :(得分:3)

您似乎需要在此处为​​您的重要性级别指定一些概率。也许像这样重新定义你的数据结构

test = {
  (0..49) => [ # most important
    "lorem",
    "ipsum"
  ],
  (50..79) => [ # semi important
    "dolor",
    "sit"
  ],
  (80..99) => [ # least important
    "amet",
    "consectetur"
  ]
}

然后做这样的事情。

while true
  rand = Kernel.rand(100)
  test.each do |range, options|
    if range.include?(rand)
      puts options.sample
    end
  end
end

您必须将这些百分比机会编辑为您想要的随机性。

PS:通过执行Kernel.rand(100) + 1(生成1到100之间的数字,而不是0到99之间的数字)并将范围向上移动1,可以使其更具可读性:(1..50) = 50%,(51..75) = 25%等等。只是一个想法。

答案 1 :(得分:2)

您没有正确的数据对象。您可以使用:

test = { important:        ["lorem", "ipsum"],
         kinda_important:  ["dolor", "sit"],
         not_so_important: ["amet", "consectetur"] }

你需要一些概率:

probs = { important: 0.5, kinda_important: 0.3, not_so_important: 0.2 }

我们现在可以生成所需的随机变量(hashprobs中的元素数量):

def deal(hash, probs, nbr)
  last = 0.0
  choices = probs.each_with_object({}) do |(group, prob),choices|
    choices[last + prob] = group
    last += prob
  end 
  nbr.times.map do
    rn = rand
    hash[choices.find { |cum,ch| rn <= cum }.last].sample
  end
end

deal(test, probs, 15)
  #=> ["amet", "amet", "consectetur", "dolor", "lorem", "dolor", "amet", 
  #    "sit", "sit", "lorem", "lorem", "lorem", "lorem", "ipsum", "ipsum"] 

下面:

choices
  #{0.5=>:important, 0.8=>:kinda_important, 1.0=>:not_so_important}

我们试一试:

n = 10_000
a = deal(test, probs, n)
a.uniq.map { |s| [s, a.count(s).to_f/n] }.sort_by(&:last).reverse.to_h
  #=> {"ipsum"      =>0.2541, "lorem"=>0.25,
  #    "dolor"      =>0.1513, "sit"  =>0.1457,
  #    "consectetur"=>0.1016, "amet" =>0.097

答案 2 :(得分:1)

如何将代码置于while循环中:

while true
 test.shuffle.each do |test|
  puts test 
 end
end