我是Ruby的新手(以及一般的编程)。我有一个使用外部文件数据的哈希,我试图获得大于1500的值的总数。
Here's my code实际上,我需要超过1500的订单数量和采购订单总价值。外部文件只是一列订单号和一列价格。我确定有一个非常简单的解决方案,但就像我说我是一个初学者并且无法弄明白。任何帮助,将不胜感激。感谢。
编辑:这是我的代码。它只是最后一次循环导致所有问题。我知道这不是正确的方法,但我无法弄清楚该怎么做。
myhash={}
file=File.open("Purchase Orders.csv", "r")
while !file.eof
line=file.readline
key,value=line.chomp.split(",")
myhash[key]=value
end
total=0
entries=myhash.length
newtotal=0
myhash.each { |key,value|
total+=value.to_f
}
puts total
puts entries
while value.to_f>1500
myhash.each {|key,value| newtotal+=value.to_f}
end
puts newtotal
答案 0 :(得分:3)
我会用ruby惯用法重写代码,希望你能检查它并找出一些提示。
prices = File.readlines("Purchase Orders.csv").map do |line|
line.chomp.split(",").last.to_f
end # array of prices
total = prices.inject(:+) # sum values
pricy = prices.select { |v| v > 1500 }
pricy_sum = pricy.inject(:+) # sum expensives
pricy_count = pricy.length # expensives’ size
puts "Total sum is: #{total}"
puts "Total expensives is: #{pricy}"
答案 1 :(得分:1)
看起来你已经扭转了你的循环。此外,对于多行代码块,使用do和end通常优于花括号,而花括号通常用于单行块(如@mudasobwa所述)。查看ruby style guide以获取更多样式指针。
myhash.each do |key,value|
newtotal+=value.to_f if value.to_f > 1500
end
puts newtotal
答案 2 :(得分:1)
<强>代码强>
def nbr_and_tot(fname)
File.foreach(fname).with_object({ nbr_over: 0, tot_over: 0 }) do |line, h|
n = line[/\d+/].to_i
if n > 1500
h[:nbr_over] += 1
h[:tot_over] += n
end
end
end
示例强>
首先让我们创建一个文件&#34; temp&#34;:
str =<<-END
:cat, 1501
:dog, 1500
:pig, 2000
END
File.write("temp", str)
#=> 33
确认文件正确无误:
puts File.read("temp")
打印
:cat, 1501
:dog, 1500
:pig, 2000
现在执行方法。
nbr_and_tot "temp"
#=> {:nbr_over=>2, :tot_over=>3501}
<强>解释强>
首先审核IO::foreach,逐行读取文件 1 并返回链接到with_object
的{{3}}枚举数}和Enumerator#with_object。
例如,
fname = "temp"
e0 = File.foreach(fname)
#=> #<Enumerator: File:foreach("temp")>
我们可以通过将此枚举器转换为数组来查看此枚举器生成的值(并传递给each_object
):
e0.to_a
#=> [":cat, 1501\n", ":dog, 1500\n", ":pig, 2000\n"]
继续,
e1 = e0.with_object({ nbr_over: 0, tot_over: 0 })
#=> #<Enumerator: #<Enumerator: 2.3.0 :171 >
e1.to_a
#=> [[":cat, 1501\n", {:nbr_over=>0, :tot_over=>0}],
# [":dog, 1500\n", {:nbr_over=>0, :tot_over=>0}],
# [":pig, 2000\n", {:nbr_over=>0, :tot_over=>0}]]
e1
生成的第一个元素将传递给块,并使用并行分配为块变量赋值:
line, h = e1.next
#=> [":cat, 1501\n", {:nbr_over=>0, :tot_over=>0}]
line
#=> ":cat, 1501\n"
h #=> {:nbr_over=>0, :tot_over=>0}
计算和n
:
s = line[/\d+/]
#=> "1501"
n = s.to_i
#=> 1501
作为n > 1500 #=> true
,我们执行以下操作:
h[:nbr_over] += 1
#=> 1
h[:tot_over] += n
#=> 1501
所以现在
h #=> {:nbr_over=>1, :tot_over=>1501}
现在e1
的第二个元素被传递给块,并执行以下步骤:
line, h = e1.next
#=> [":dog, 1500\n", {:nbr_over=>1, :tot_over=>1501}]
line
#=> ":dog, 1500\n"
h #=> {:nbr_over=>1, :tot_over=>1501}
n = line[/\d+/].to_i
#=> 1500
作为n > 1500 #=> fasle
,跳过此行。 e1
生成的最后一个元素的处理类似于第一个元素的处理。
1 File
是IO
(File < IO #=> true
)的子类,因此IO
类方法(例如foreach
)通常会在文件上调用class(File.foreach...
)。