我有一个CSV文件,如:
123,hat,19.99
321,cap,13.99
我有这段代码:
products_file = File.open('text.txt')
while ! products_file.eof?
line = products_file.gets.chomp
puts line.inspect
products[ line[0].to_i] = [line[1], line[2].to_f]
end
products_file.close
正在读取文件。虽然它不在文件的末尾,但它会读取每一行。我不需要line.inspect
。但它将文件存储在我的产品哈希中的数组中。
现在我想从哈希中提取最小值和最大值。 到目前为止我的代码是:
read_file = File.open('text.txt', "r+").read
read_file.(?) |line|
products[ products.length] = gets.chomp.to_f
products.min_by { |x| x.size }
smallest = products
puts "Your highest priced product is #{smallest}"
现在我read_file.(?) |line|
之后没有任何东西,所以我收到了错误。我尝试使用min
或max
,但都没有效果。
答案 0 :(得分:4)
不使用CSV
如果我正确理解您的问题,您不必使用CSV
类方法:只需将文件(较少的标题)读入数组并确定最小值和最大值,如下所示:
arr = ["123,hat,19.99", "321,cap,13.99",
"222,shoes,33.41", "255,shirt,19.95"]
arr.map { |s| s.split(',').last.to_f }.minmax
#=> [13.99, 33.41]
或
arr.map { |s| s[/\d+\.\d+$/].to_f }.minmax
#=> [13.99, 33.41]
如果您想要相关记录:
arr.minmax_by { |s| s.split(',').last.to_f }
=> ["321,cap,13.99", "222,shoes,33.41"]
使用CSV
如果您希望使用CSV
将文件读入数组:
arr = [["123", "hat", "19.99"],
["321", "cap", "13.99"],
["222", "shoes", "33.41"],
["255", "shirt", "19.95"]]
然后
arr.map(&:last).minmax
# => ["13.99", "33.41"]
或
arr.minmax_by(&:last)
#=> [["321", "cap", "13.99"],
# ["222", "shoes", "33.41"]]
如果你想要记录。请注意,在CSV示例中,我没有将最后一个字段转换为float,假设所有记录都有两位小数。
答案 1 :(得分:2)
您应该使用内置的CSV类:
require 'CSV'
data = CSV.read("text.txt")
data.sort!{ |row1, row2| row1[2].to_f <=> row2[2].to_f }
least_expensive = data.first
most_expensive = data.last
Array#sort!
方法会修改data
,因此会根据块中的条件对其进行排序,以供日后使用。如您所见,该块根据索引2处每行中的值进行排序 - 在您的情况下,是价格。顺便说一句,您不需要将这些值转换为浮点数 - 字符串将以相同的方式排序。如果您有前导非数字字符(例如to_f
),则$
停止工作,因此您可能会发现在排序过程中将值保持为字符串会更好。
然后,您可以在闲暇时获得最便宜,最便宜或最便宜的,或其他任何东西。