我目前正在处理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
答案 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