在此 CashRegister 中查找产品的频率 class
Find product's frequency in this CashRegister class
我有 3 个简单的 类 CashRegister、Bill 和 Position。 CashRegister 由 Bill 对象组成,Bill 对象由 Position 对象组成。它们的实现方式如下
class CashRegister
def initialize
@bills = []
end
def product_frequency
#???
end
def << bill
@bills << bill
self
end
end
class Bill
attr_reader :positions,:nr
protected :positions
def initialize(nr)
@nr = nr
@positions = []
end
def << pos
@positions << pos
self
end
end
class Position
attr_reader :product,:quantity,:price
def initialize(product,quantity,single_price)
@product = product
@quantity = quantity
@price = single_price * quantity
end
end
我想编写一个 product_frequency 方法来计算产品在 CashRegister 中的购买频率。此方法 returns 一个散列结果,以产品为键,以频率为值。
一个例子是:
pos1 = Position.new('Chicken', 5, 12)
pos2 = Position.new('Soup', 6, 24)
pos3 = Position.new('Burger', 3, 19)
pos4 = Position.new('Chicken', 2, 12)
pos5 = Position.new('Soup', 8, 24)
pos6 = Position.new('Burger', 9, 19)
bill1 = Bill.new(1) << pos1 << pos2 << pos3 #Chicken: 5;Soup: 6;Burger: 3
bill2 = Bill.new(2) << pos4 << pos3 << pos2 #Chicken: 2;Soup: 6;Burger: 3
bill3 = Bill.new(3) << pos6 << pos6 << pos6 #Chicken: 0;Soup: 0;Burger: 27
bill4 = Bill.new(4) << pos4 << pos5 << pos4 #Chicken: 4;Soup: 8;Burger: 0
my_cash_register = CashRegister.new << bill1 << bill2 << bill3 << bill4
my_cash_register.product_frequency #{'Chicken' => 11, 'Soup' => 20, 'Burger' => 33}
我怎样才能达到那个结果?
如果您只是想统计每个产品被购买了多少次,那么这里是:
def product_frequency
product_frequency = {}
@bills.each do |bill|
bill.positionen.each do |position|
@product_frequency[position.product] ||= 0
@product_frequency[position.product] += position.quantity
end
end
product_frequency
end
这只是一种方法。代码很简单,所以我想你可以理解它是如何工作的
您可以为每个嵌套 class 定义 #frequency
,然后递归地收集哈希值。
class Hash
def additive_merge!(hash)
hash.each { |k,v| self[k] ? self[k] += v : self[k] = v }
self
end
end
class CashRegister
def initialize
@bills = []
end
def product_frequency
@bills.map(&:frequency).reduce(&:additive_merge!)
end
def << bill
@bills << bill
self
end
end
class Bill
attr_reader :positionen,:nr
protected :positionen
def initialize(nr)
@nr = nr
@positions = []
end
def << pos
@positions << pos
self
end
def frequency
@positions.map(&:frequency).reduce(&:additive_merge!)
end
end
class Position
attr_reader :product,:quantity,:price
def initialize(product,quantity,single_price)
@product = product
@quantity = quantity
@price = single_price * quantity
end
def frequency
{ product => quantity }
end
end
主要取自 Bartosz Bonisławski 的解决方案。但是由于 bill
中的 positionen
是 protected
,我们首先必须通过在 Bill
中定义一个 each
函数来使其可访问,该函数接受一个块并应用它positions
中的每个 position
。我们也为 CashRegister
.
做同样的事情
class CashRegister
def initialize
@bills = []
end
def each(&block)
@bills.each(&block)
end
def product_frequency
result = {}
each { |bill|
bill.each { |position|
result[position.product] ||= 0
result[position.product] += position.quantity
}
}
result
end
def << bill
@bills << bill
self
end
end
class Bill
attr_reader :positions,:nr
protected :positions
def initialize(nr)
@nr = nr
@positions = []
end
def each(&block)
@positions.each(&block)
end
def << pos
@positions << pos
self
end
end
class Position
attr_reader :product,:quantity,:price
def initialize(product,quantity,single_price)
@product = product
@quantity = quantity
@price = single_price * quantity
end
end
我有 3 个简单的 类 CashRegister、Bill 和 Position。 CashRegister 由 Bill 对象组成,Bill 对象由 Position 对象组成。它们的实现方式如下
class CashRegister
def initialize
@bills = []
end
def product_frequency
#???
end
def << bill
@bills << bill
self
end
end
class Bill
attr_reader :positions,:nr
protected :positions
def initialize(nr)
@nr = nr
@positions = []
end
def << pos
@positions << pos
self
end
end
class Position
attr_reader :product,:quantity,:price
def initialize(product,quantity,single_price)
@product = product
@quantity = quantity
@price = single_price * quantity
end
end
我想编写一个 product_frequency 方法来计算产品在 CashRegister 中的购买频率。此方法 returns 一个散列结果,以产品为键,以频率为值。 一个例子是:
pos1 = Position.new('Chicken', 5, 12)
pos2 = Position.new('Soup', 6, 24)
pos3 = Position.new('Burger', 3, 19)
pos4 = Position.new('Chicken', 2, 12)
pos5 = Position.new('Soup', 8, 24)
pos6 = Position.new('Burger', 9, 19)
bill1 = Bill.new(1) << pos1 << pos2 << pos3 #Chicken: 5;Soup: 6;Burger: 3
bill2 = Bill.new(2) << pos4 << pos3 << pos2 #Chicken: 2;Soup: 6;Burger: 3
bill3 = Bill.new(3) << pos6 << pos6 << pos6 #Chicken: 0;Soup: 0;Burger: 27
bill4 = Bill.new(4) << pos4 << pos5 << pos4 #Chicken: 4;Soup: 8;Burger: 0
my_cash_register = CashRegister.new << bill1 << bill2 << bill3 << bill4
my_cash_register.product_frequency #{'Chicken' => 11, 'Soup' => 20, 'Burger' => 33}
我怎样才能达到那个结果?
如果您只是想统计每个产品被购买了多少次,那么这里是:
def product_frequency
product_frequency = {}
@bills.each do |bill|
bill.positionen.each do |position|
@product_frequency[position.product] ||= 0
@product_frequency[position.product] += position.quantity
end
end
product_frequency
end
这只是一种方法。代码很简单,所以我想你可以理解它是如何工作的
您可以为每个嵌套 class 定义 #frequency
,然后递归地收集哈希值。
class Hash
def additive_merge!(hash)
hash.each { |k,v| self[k] ? self[k] += v : self[k] = v }
self
end
end
class CashRegister
def initialize
@bills = []
end
def product_frequency
@bills.map(&:frequency).reduce(&:additive_merge!)
end
def << bill
@bills << bill
self
end
end
class Bill
attr_reader :positionen,:nr
protected :positionen
def initialize(nr)
@nr = nr
@positions = []
end
def << pos
@positions << pos
self
end
def frequency
@positions.map(&:frequency).reduce(&:additive_merge!)
end
end
class Position
attr_reader :product,:quantity,:price
def initialize(product,quantity,single_price)
@product = product
@quantity = quantity
@price = single_price * quantity
end
def frequency
{ product => quantity }
end
end
主要取自 Bartosz Bonisławski 的解决方案。但是由于 bill
中的 positionen
是 protected
,我们首先必须通过在 Bill
中定义一个 each
函数来使其可访问,该函数接受一个块并应用它positions
中的每个 position
。我们也为 CashRegister
.
class CashRegister
def initialize
@bills = []
end
def each(&block)
@bills.each(&block)
end
def product_frequency
result = {}
each { |bill|
bill.each { |position|
result[position.product] ||= 0
result[position.product] += position.quantity
}
}
result
end
def << bill
@bills << bill
self
end
end
class Bill
attr_reader :positions,:nr
protected :positions
def initialize(nr)
@nr = nr
@positions = []
end
def each(&block)
@positions.each(&block)
end
def << pos
@positions << pos
self
end
end
class Position
attr_reader :product,:quantity,:price
def initialize(product,quantity,single_price)
@product = product
@quantity = quantity
@price = single_price * quantity
end
end