在Ruby中计算超过一定数量的值的数量

时间:2017-05-30 21:27:18

标签: ruby

我目前正在处理ruby中的.csv文件,而我正试图弄清楚如何计算文件中超过60的项目数。

我已将csv文件导入哈希并计算了项目总数,但我想知道如何计算现在超过60的项目数。

这是我正在寻找的一个例子

csv.csv

55, 56
60, 61
63, 9
3, 62

到目前为止我的代码:

myhash=[]
myhash1=[]
total=0
count=0
file=File.open('csv.csv',"r")

???

puts count 

预期输出:4

4 个答案:

答案 0 :(得分:3)

有多种方法可以解决这个问题。这是一种方法,可以一次性完成整个操作,甚至无需循环遍历每一行:

File
  .read('csv.csv') # Read the file into a ruby String
  .split(/,|\n/)   # Convert into an Array of each string (splitting on commas OR newlines) (e.g. ['55', '56', '60', ... ])
  .map(&:to_i)     # Convert into an Array of each integer (e.g. [55, 56, 60, ... ])
  .count { |n| n >= 60 }

这是一种类似的方法,它反过来遍历每一行并将计数添加到变量中。如果你有一个非常大的文件,那么使用这样的foreach会更好 - 因为你不会一次将它全部加载到内存中:

total = 0
File.foreach('csv.csv') do |line|
  total += line.split(',').count {|n| n.to_i >= 60 }
end

这是另一种实际使用ruby的CSV library的方法,所以你不需要明确地分割逗号:

require 'csv'

total = 0
CSV.foreach('csv.csv') do |row|
  total += row.count {|n| n.to_i >= 60 }
end

答案 1 :(得分:0)

虽然我通常告诫不要使用天真的方式来处理CSV数据,但如果您的CSV文件确实是所有数字,那么我认为使用CSV模块是过度的。您可以使用File.foreach迭代文件的行和String#scan来迭代文件中的数字。

n = 0
File.foreach("csv.csv") do |line|
  line.scan(/\d+/) {|s| num += 1 if s.to_i >= 60 }
end

p n # => 4

此方法的好处是不会立即将整个文件读入内存,也不会创建大型中间阵列。

你可以在repl.it上看到它(差不多):https://repl.it/IY5X(它的不同只是因为你无法读取repl.it上的文件。)

答案 2 :(得分:0)

我知道这样做的最短路径是:

File.read('foo.csv').scan(/\d+/).select { |d| d.to_i > 60 ).size
  

不要忘记Enumerable#count

好点:

DATA.read.scan(/\d+/).count { |s| s.to_i > 60 }  # => 3

这些方面的缺点是它们不具备可扩展性。有关详细信息,请参阅“Why is "slurping" a file not a good practice?”。

答案 3 :(得分:0)

如果所有值都得到平等对待:

require 'csv'

CSV.read('input.csv').flatten.map(&:to_i).count { |i| i >= 60 }
# => 4