def pick_random_line
chosen_line = nil
File.foreach("id'sForCascade.txt").each_with_index do |line, id|
chosen_line = line if rand < 1.0/(id+1)
end
return chosen_line
end`enter code here
嘿,我正在尝试让代码选择37个不同的行。那么我该如何做到这一点让我感到困惑和困惑。
答案 0 :(得分:0)
您可以这样做:
input_lines = File.foreach("test.txt").map(&:to_s)
output_lines = []
37.times do
output_lines << input_lines.delete_at(rand(input_lines.length))
end
puts output_lines
这样可以确保您不会抓住重复的行并且不需要进行任何花哨的检查。
但是,如果您的文件少于37行,这可能会导致问题,它还会假定您的文件存在。
编辑:
正在发生的事情是rand
调用现在正在根据输入行的大小更改调用它的范围。并且由于您在删除时删除索引,因此长度会缩小,并且您不会冒重复行的风险。
答案 1 :(得分:0)
假设您不希望同一行重复多次,我会在一行中这样做:
File.read("test.txt").split("\n").shuffle.first(37)
File.read("test.txt")
读取整个文件。
split("\n")
根据\n
分隔符将文件拆分为行(我假设您的文件是文本的,并且用新行字符分隔行)。
shuffle
是一种非常方便的Array
方法,可随机随机排列。你可以在这里读到它:
http://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-shuffle
最后,first(37)
为您提供了混洗数组中的前37行。这些保证在shuffle
操作中是随机的。
答案 2 :(得分:0)
如果要从大文件中保存相对较少的行,将整个文件读入数组(然后随机选择行)可能会很昂贵。最好计算文件中的行数,随机选择行偏移,然后将这些偏移处的行保存到数组中。这种方法并不比前一种方法更难实现,但即使当前应用程序中的文件不是太大,该方法也会更加健壮。 1
假设您的文件名由FName
提供。以下是计算文件中行数的三种方法:
计算行数,字面意思
cnt = File.foreach(FName).reduce(0) { |c,_| c+1 }
使用$.
File.foreach(FName) {}
cnt = $.
在Unix系列计算机上,shell-out到操作系统
cnt = %x{wc -l #{FName}}.split.first.to_ii
第三种选择非常快。
要保存的1
行的随机偏移量(基数n
)可按如下方式计算:
lines = (1..cnt).to_a.sample(n).sort
将这些偏移处的线保存到数组是很简单的;例如:
File.foreach(FName).with_object([]) do |line,a|
if lines.first == $.
a << line
lines.shift
break a if lines.empty?
end
end
请注意,读取第一行后的$. #=> 1
,读取每一行后$.
递增1
。 (因此基线1
用于线偏移。)
1此外,许多程序员,不仅仅是Rubiest,都被大量积累的东西所击退,然后抛弃了所有东西。