从CSV文件中提取最小值和最大值

时间:2015-03-04 21:20:30

标签: ruby csv

我有一个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|之后没有任何东西,所以我收到了错误。我尝试使用minmax,但都没有效果。

2 个答案:

答案 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),则$停止工作,因此您可能会发现在排序过程中将值保持为字符串会更好。

然后,您可以在闲暇时获得最便宜,最便宜或最便宜的,或其他任何东西。