所以下面的代码是我试图减少尽可能少的行。还有其他任何红宝石技巧可以缩短它吗?我感谢任何人都可以提供的帮助。
文章类:
class Article
attr_accessor :id, :price, :quantity
def initialize(id, price, quantity)
@id, @price, @quantity = id, Float(price), quantity.to_i
end
end
订单类:
class Order
def initialize(name)
@a, i = [], 0
input = File.open(name, "r")
while(id = input.gets.chomp)
j, price = 0, input.gets.chomp
while(j<@a.length)
if(@a[j].id.eql?(id.to_i))
@a[j].quantity += 1
end
end
else
@a[i] = new Article(id,price,1)
i+=1
end
end
end
def orderCost
sum = 0
@a.each { |e| sum+=(e.price * e.quantity)}
sum = ((sum*1.07) + 2.99)
end
def displaySelectArticles
min, max = @a[0], @a[0]
@a.each do |e|
if(min.cost > e.cost)
min = e
end
if(max.cost < e.cost)
max = e
end
sum += e.cost*e.quantity and q += e.quantity
end
puts "Min: #{min.cost} | Max: #{max.cost} | Avg: #{Float(sum)/q}"
end
end
答案 0 :(得分:0)
我尽力而为,但你的初始化方法对我来说没有任何合理意义。希望这至少可以引导您走向正确的方向。 免责声明:这些都没有经过测试,而且我用我记得的方法写下了它。
class Order
def initialize(name)
@a, i = [], 0
File.readlines(name) do |line|
# This while loop makes no sense to me
# Seems like a surefire infiniteloop because if id = 3, it is always true
# Maybe you meant to do an operator like == for comparison
while(id = line)
j, price = 0, line
while j < @a.length
@a[j].quantity += 1 if(@a[j].id.eql?(id.to_i))
end
else
@a[i] = new Article(id, price, 1)
i += 1
end
end
end
def orderCost
# I would probably make this two lines because its unreadable
(@a.inject(0) { |accum, e| accum + (e.price * e.quantity) } * 1.07) + 2.99
end
def displaySelectArticles
min, max = @a[0], @a[0]
@a.each do |e|
min = e if min.cost > e.cost
max = e if max.cost < e.cost
sum += e.cost * e.quantity
q += e.quantity # I have no idea how you got a q
end
puts "Min: #{min.cost} | Max: #{max.cost} | Avg: #{Float(sum)/q}"
end
end
答案 1 :(得分:-1)
文章类需要认真关注,因为那里有混乱的垃圾 三个变量同时分配。把它分成三个非常 简单的任务:
class Article
attr_accessor :id, :price, :quantity
def initialize(id, price, quantity)
@id = id
@price = price.to_f
@quantity = quantity.to_i
end
end
使用x.to_f
优于Float(x)
,这是一种更温和的方法
转换。如果您正在进行财务计算,我强烈鼓励
你可以用BigDecimal之类的东西
因为浮点数是众所周知的问题。 1.99美元有办法
成为$ 1.989999423489,在四舍五入时可能会“失去”一分钱
或者那里。 BigDecimal类通过将值表示为精确来避免这种情况。
其余的基本上是在解决不使用Enumerable
的问题
有效地,而是编写自己的例程来做简单的事情:
class Order
def initialize(name)
@items = [ ]
File.open(name, "r") do |input|
while(id = input.gets.chomp)
price = input.gets.chomp
# find locates the first matching thing in the array, if any.
existing = @items.find do |item|
item.id == id
end
if (existing)
existing.quantity += 1
else
items << Article.new(id, price, 1)
end
end
end
def item_cost
# Inject is good at iterating and accumulating
@items.inject(0.0) do |sum, item|
sum + item.price * item.quantity
end
end
def item_count
@items.inject(0) do |sum, item|
sum + item.quantity
end
end
def order_cost
item_cost * 1.07 + 2.99
end
def display_select_articles
# minmax_by finds min and max entries based on arbitrary criteria
min, max = @items.minmax_by { |item| item.price }
sum = item_cost
count = item_count
puts "Min: %f | Max: %f | Avg: %f" % [
min ? min.cost : 0.0,
max ? max.cost : 0.0,
count > 0.0 ? (sum / count) : 0.0
]
end
end
尽可能使用谷物,这意味着使用Ruby的结构及其原生方法。你偏离这个越多,你需要编写的代码就越多,你的代码就会变得越丑。有时你正在解决一个棘手的问题而你别无选择,但这个例子不是其中之一。如果你只是用Ruby方式做的话,这里的一切都比较简单。