在Ruby中使用每个if语句

时间:2019-07-06 08:59:04

标签: ruby if-statement hash each hash-of-hashes

我首先要道歉,因为我不确定这是否完全有意义,但我想为您提供尽可能多的背景信息。我正在上一堂课,试图教我迭代哈希和嵌套哈希。我已经为此工作了几天,并且一直在挣扎,现在我想我投入了太多的代码行,看起来可能有些草率。

因此,首先对方法进行以下项目和测试的测试:

describe "Grocer" do
  let(:items) do
    [
      {"AVOCADO" => {:price => 3.00, :clearance => true}},
      {"KALE" => {:price => 3.00, :clearance => false}},
      {"BLACK_BEANS" => {:price => 2.50, :clearance => false}},
      {"ALMONDS" => {:price => 9.00, :clearance => false}},
      {"TEMPEH" => {:price => 3.00, :clearance => true}},
      {"CHEESE" => {:price => 6.50, :clearance => false}},
      {"BEER" => {:price => 13.00, :clearance => false}},
      {"PEANUTBUTTER" => {:price => 3.00, :clearance => true}},
      {"BEETS" => {:price => 2.50, :clearance => false}},
      {"SOY MILK" => {:price => 4.50, :clearance => true}}
    ]
  end

  let(:coupons) do
    [
      {:item => "AVOCADO", :num => 2, :cost => 5.00},
      {:item => "BEER", :num => 2, :cost => 20.00},
      {:item => "CHEESE", :num => 3, :cost => 15.00}
    ]
  end

这些就是它们要经过的项目。以及优惠券及其价值。以下是apply_coupons将通过的测试:

  describe "#apply_coupons" do
    context "base case - with perfect coupon (number of items identical):" do
      before(:each) do
        @avocado = find_item('AVOCADO')
        @avocado_coupon = coupons.find { |coupon| coupon[:item] == "AVOCADO" }
        @cart = [@avocado, @avocado]
        @consolidated_cart = consolidate_cart(@cart)
        @avocado_result = apply_coupons(@consolidated_cart, [@avocado_coupon])
      end

      it "adds a new key, value pair to the cart hash called 'ITEM NAME W/COUPON'" do
        expect(@avocado_result.keys).to include("AVOCADO W/COUPON")
      end

      it "adds the coupon price to the property hash of couponed item" do
        expect(@avocado_result["AVOCADO W/COUPON"][:price]).to eq(2.50)
      end

      it "adds the count number to the property hash of couponed item" do
        expect(@avocado_result["AVOCADO W/COUPON"][:count]).to eq(2)
      end

      it "removes the number of discounted items from the original item's count" do
        expect(@avocado_result["AVOCADO"][:price]).to eq(3.00)
        expect(@avocado_result["AVOCADO"][:count]).to eq(0)
      end

      it "remembers if the item was on clearance" do
        expect(@avocado_result["AVOCADO W/COUPON"][:clearance]).to eq(true)
      end

    end

    context "more advanced cases:" do

      it "accounts for when there are more items than the coupon allows" do
        cheese = find_item('CHEESE')
        cart = Array.new(5, cheese)
        consolidated_cart = consolidate_cart(cart)
        cheese_coupon = find_coupon("CHEESE")
        cheese_result = apply_coupons(consolidated_cart, [cheese_coupon])

        expect(cheese_result["CHEESE"][:price]).to eq(6.50)
        expect(cheese_result["CHEESE"][:count]).to eq(2)
        expect(cheese_result["CHEESE W/COUPON"][:price]).to eq(5.00)
        expect(cheese_result["CHEESE W/COUPON"][:count]).to eq(3)
        expect(cheese_result["CHEESE W/COUPON"][:clearance]).to eq(false)
      end

      it "doesn't break if the coupon doesn't apply to any items" do
        cheese = find_item('CHEESE')
        cart = Array.new(2, cheese)
        consolidated_cart = consolidate_cart(cart)

        irrelevant = apply_coupons(consolidated_cart, [find_coupon("AVOCADO")])
        expect(irrelevant["CHEESE"][:price]).to eq(6.50)
        expect(irrelevant["CHEESE"][:count]).to eq(2)
        expect(irrelevant.keys).to_not include("AVOCADO W/COUPON")
        expect(irrelevant.keys).to_not include("AVOCADO")
      end

      it "can apply multiple coupons" do
        avocado = find_item('AVOCADO')
        cheese = find_item('CHEESE')
        cart = Array.new(4, cheese)
        3.times { cart << avocado }
        consolidated_cart = consolidate_cart(cart)
        coupons = [find_coupon("AVOCADO"), find_coupon("CHEESE")]

        multiple_coupons = apply_coupons(consolidated_cart, coupons)

        ["AVOCADO", "CHEESE"].each { |item| expect(multiple_coupons[item][:count]).to eq(1) }
        expect(multiple_coupons["CHEESE"][:price]).to eq(6.50)
        expect(multiple_coupons["AVOCADO"][:price]).to eq(3.00)
        expect(multiple_coupons["CHEESE W/COUPON"][:price]).to eq(5.00)
        expect(multiple_coupons["CHEESE W/COUPON"][:count]).to eq(3)
        expect(multiple_coupons["CHEESE W/COUPON"][:clearance]).to eq(false)
        expect(multiple_coupons["AVOCADO W/COUPON"][:price]).to eq(2.50)
        expect(multiple_coupons["AVOCADO W/COUPON"][:count]).to eq(2)
        expect(multiple_coupons["AVOCADO W/COUPON"][:clearance]).to eq(true)
      end

      it "doesn't break if there is no coupon" do
        cheese = items.find { |item| item['CHEESE'] }
        cart = [cheese, cheese]
        consolidated_cart = consolidate_cart(cart)
        no_coupon_result = apply_coupons(consolidated_cart, [])

        expect(no_coupon_result["CHEESE"][:price]).to eq(6.50)
        expect(no_coupon_result["CHEESE"][:count]).to eq(2)
      end

      it "can increment coupon count if two are applied" do
        avocado = find_item("AVOCADO")
        coupon = find_coupon("AVOCADO")
        consol_cart = consolidate_cart([avocado, avocado, avocado, avocado, avocado])
        two_coupon_result = apply_coupons(consol_cart, [coupon, coupon])

        expect(two_coupon_result["AVOCADO"][:count]).to eq(1)
        expect(two_coupon_result["AVOCADO W/COUPON"][:price]).to eq(2.50)
        expect(two_coupon_result["AVOCADO"][:price]).to eq(3.00)
        expect(two_coupon_result["AVOCADO W/COUPON"][:count]).to eq(4)
      end
    end
  end

现在,到目前为止,我的代码一直沿用到应用多个优惠券的先例,而且
可以申请多个优惠券(失败-1) 如果没有优惠券,则不会中断(失败-2) 如果应用两个,则可以增加优惠券数量(失败-3):

def apply_coupons(cart, coupons)
  #cart is a hash with 2 keys with a nested hash with 3 values
  #coupons is an array with a hash with 3 keys and 3 values
  #if coupons[0].values.include?(cart.keys[0]) will find avocado in coupon
  #coupons[0].values[0] is AVOCADO in coupon
  #cart.keys[0] is AVOCADO in cart
  #coupons[0].values[0] + " W/COUPON" creates "AVOCADO W/COUPON"
  #coupons[0].values[1] = 2 the number of coupons
  #coupons[0].values[2] = 5.0 which is the number off need to be divded by 2(number of coupons)

  applyCoupons = {}

    coupons.each do |k| 

    if coupons.include?(" W/COUPON")
      applyCoupons[coupons[0].values[0] + " W/COUPON"]
      applyCoupons[coupons[0].values[0] + " W/COUPON"][:price] = coupons[0].values[2] / coupons[0].values[1] 
      applyCoupons[coupons[0].values[0] + " W/COUPON"][:clearance] = cart.values[0].has_value?(true)
      applyCoupons[coupons[0].values[0]][:count] += 1
    end

    if cart.keys[0] == coupons[0].values[0] 
      applyCoupons[cart.keys[0]] = cart.values[0]
      applyCoupons[coupons[0].values[0] + " W/COUPON"] = {}
      applyCoupons[coupons[0].values[0] + " W/COUPON"][:price] = coupons[0].values[2] / coupons[0].values[1] 
       applyCoupons[coupons[0].values[0] + " W/COUPON"][:clearance] = cart.values[0].has_value?(true)
       applyCoupons[coupons[0].values[0] + " W/COUPON"][:count] = coupons[0].values[1]
       applyCoupons[coupons[0].values[0]][:count] -= coupons[0].values[1]
    else
      applyCoupons[cart.keys[0]] = cart.values[0]
    end
  end
  applyCoupons
end

我得到的错误: 失败:

1)杂货商#apply_coupons更多高级案例:可以申请多个优惠券      失败/错误:[“ AVOCADO”,“ CHEESE”]。each {| item | Expect(multiple_coupons [item] [:count])。eq(1)}

 NoMethodError:
   undefined method `[]' for nil:NilClass
 # ./spec/grocer_spec.rb:121:in `block (5 levels) in <top (required)>'
 # ./spec/grocer_spec.rb:121:in `each'
 # ./spec/grocer_spec.rb:121:in `block (4 levels) in <top (required)>'

这是一个很大的问题,但是我正在学习,所以我们感谢您的帮助。很想学习使我的代码更简单的方法。

1 个答案:

答案 0 :(得分:-1)

def apply_coupons(cart, coupons)
  coupons.each do |coupon|
    if cart.keys.include?(coupon[:item])
      if cart[coupon[:item]][:count] >= coupon[:num]
        itemwithCoupon = "#{coupon[:item]} W/COUPON"
        if cart[itemwithCoupon]
          cart[itemwithCoupon][:count] += coupon[:num]
          cart[coupon[:item]][:count] -= coupon[:num]
        else
          cart[itemwithCoupon] = {}
          cart[itemwithCoupon][:price] = (coupon[:cost] / coupon[:num])
          cart[itemwithCoupon][:clearance] = cart[coupon[:item]][:clearance]
          cart[itemwithCoupon][:count] = coupon[:num]
          cart[coupon[:item]][:count] -= coupon[:num]
        end
      end
    end
  end
  cart

end