【问题标题】:How do I conditionally merge hashes and add values?如何有条件地合并哈希并添加值?
【发布时间】:2011-11-22 03:32:23
【问题描述】:

我被困在合并一些哈希以获得我需要的结果。

哈希包含订单总价的明细,例如订阅中所有订单的商品价格、税金和运费。我正在尝试动态执行此操作,因为并非所有订单都收取税费,甚至相同税或运费。

这就是我正在处理的“最坏情况”:

#First order - has charges for Canadian GST and HST
{:orderhdr_id=>17654122, :order_item_seq=>1, :order_item_amt_break_seq=>1, :order_item_break_type=>0, :local_amount=>8.16, :base_amount=>8.16, :orig_base_amount=>149, :tax_delivery=>0, :tax_active=>0}
{:orderhdr_id=>17654122, :order_item_seq=>1, :order_item_amt_break_seq=>2, :order_item_break_type=>1, :local_amount=>0.41, :base_amount=>0.41, :state=>"ON", :tax_type=>"GST", :tax_rate_category=>"STD", :orig_base_amount=>7.45, :tax_rate=>5, :tax_delivery=>0, :tax_active=>1, :tx_incl=>1}
{:orderhdr_id=>17654122, :order_item_seq=>1, :order_item_amt_break_seq=>3, :order_item_break_type=>1, :local_amount=>0.65, :base_amount=>0.65, :state=>"ON", :tax_type=>"HST", :tax_rate_category=>"STD", :orig_base_amount=>11.92, :tax_rate=>8, :tax_delivery=>0, :tax_active=>1, :tx_incl=>1}
#Second order - has only one charge for tax
{:orderhdr_id=>1815296, :order_item_seq=>1, :order_item_amt_break_seq=>1, :order_item_break_type=>0, :local_amount=>76.52, :base_amount=>76.52, :orig_base_amount=>99.95, :tax_delivery=>0, :tax_active=>0}
{:orderhdr_id=>1815296, :order_item_seq=>1, :order_item_amt_break_seq=>2, :order_item_break_type=>1, :local_amount=>4.59, :base_amount=>4.59, :orig_base_amount=>6, :tax_delivery=>0, :tax_active=>1}
#Third order - has charge for shipping
{:orderhdr_id=>6112412, :order_item_seq=>1, :order_item_amt_break_seq=>1, :order_item_break_type=>0, :local_amount=>21.34, :base_amount=>21.34, :orig_base_amount=>99.95, :tax_delivery=>0, :tax_active=>0}
{:orderhdr_id=>6112412, :order_item_seq=>1, :order_item_amt_break_seq=>2, :order_item_break_type=>2, :local_amount=>4.7, :base_amount=>4.7, :orig_base_amount=>22, :tax_delivery=>0, :tax_active=>0}

:order_item_break_type 确定收费的类型、项目、税金、运费。

如果 :order_item_break_type 是 0 或 2,则从 :orig_base_amount 中减去 :base_amount 并将其添加到该中断类型的总和中。对于:order_item_break_type 等于1,我需要总结:orig_base_amount:base_amount 的差异,但是我需要将不同的税分开。

因此,对于上述订单,我应该得到以下结果:

:break_type = 0 | total = 242.88
:break_type = 1, :state = ON, :tax_type = GST, :tax_rate_category = STD | total = 7.04
:break_type = 1, :state = ON, :tax_type = HST, :tax_rate_category = STD | total = 11.27
:break_type = 1 | total = 1.41
:break_type = 2 | total = 17.30

我将这些哈希值放在一个名为 @amounts 的数组中。

我脑子里有诸如merge!injectshift 之类的方法,但无法将它们放在一起。

【问题讨论】:

  • 不清楚结果与订单的关系。也就是说,我看到三个订单和五个结果。你能澄清一下吗?
  • 结果是:orig_base_amount - :base_amount 的总和,每个费用按:break_type:state:tax_type:tax_rate_category 的唯一组合分组。我倾向于看待它的方式是,与有 3 个订单和 5 个结果相反,有 7 个费用减少到 5 个结果。谢谢!

标签: ruby hash


【解决方案1】:

这个怎么样?不过,我真的不知道你在那里做什么。

@amounts = [
#First order - has charges for Canadian GST and HST
{:orderhdr_id=>17654122, :order_item_seq=>1, :order_item_amt_break_seq=>1, :order_item_break_type=>0, :local_amount=>8.16, :base_amount=>8.16, :orig_base_amount=>149, :tax_delivery=>0, :tax_active=>0},
{:orderhdr_id=>17654122, :order_item_seq=>1, :order_item_amt_break_seq=>2, :order_item_break_type=>1, :local_amount=>0.41, :base_amount=>0.41, :state=>"ON", :tax_type=>"GST", :tax_rate_category=>"STD", :orig_base_amount=>7.45, :tax_rate=>5, :tax_delivery=>0, :tax_active=>1, :tx_incl=>1},
{:orderhdr_id=>17654122, :order_item_seq=>1, :order_item_amt_break_seq=>3, :order_item_break_type=>1, :local_amount=>0.65, :base_amount=>0.65, :state=>"ON", :tax_type=>"HST", :tax_rate_category=>"STD", :orig_base_amount=>11.92, :tax_rate=>8, :tax_delivery=>0, :tax_active=>1, :tx_incl=>1},
#Second order - has only one charge for tax
{:orderhdr_id=>1815296, :order_item_seq=>1, :order_item_amt_break_seq=>1, :order_item_break_type=>0, :local_amount=>76.52, :base_amount=>76.52, :orig_base_amount=>99.95, :tax_delivery=>0, :tax_active=>0},
{:orderhdr_id=>1815296, :order_item_seq=>1, :order_item_amt_break_seq=>2, :order_item_break_type=>1, :local_amount=>4.59, :base_amount=>4.59, :orig_base_amount=>6, :tax_delivery=>0, :tax_active=>1},
#Third order - has charge for shipping
{:orderhdr_id=>6112412, :order_item_seq=>1, :order_item_amt_break_seq=>1, :order_item_break_type=>0, :local_amount=>21.34, :base_amount=>21.34, :orig_base_amount=>99.95, :tax_delivery=>0, :tax_active=>0},
{:orderhdr_id=>6112412, :order_item_seq=>1, :order_item_amt_break_seq=>2, :order_item_break_type=>2, :local_amount=>4.7, :base_amount=>4.7, :orig_base_amount=>22, :tax_delivery=>0, :tax_active=>0},
]

@totals = Hash.new(0)

@amounts.group_by{|row| row[:order_item_break_type]}.each do |break_type, rows|

  rows.each do |row|

    key = [break_type, row[:tax_type]]
    @totals[key] += row[:orig_base_amount] - row[:base_amount]

  end
end

@totals
# => {[0, nil]=>242.88,
#     [1, "GST"]=>7.04,
#     [1, "HST"]=>11.27,
#     [1, nil]=>1.4100000000000001,
#     [2, nil]=>17.3}

【讨论】:

  • 我认为这可能行得通。我将不得不经历几个不同的场景,但乍一看它看起来不错。
  • 其实你根本不需要外循环(group_by)。只需使用injecteach_with_object 而不是each
  • 抱歉,我花了这么长时间才回到这个……疯狂的时间表。不管怎样,我试过了,它完全符合我的要求,所以,谢谢!
猜你喜欢
  • 2016-03-30
  • 1970-01-01
  • 2023-02-06
  • 1970-01-01
  • 2012-01-14
  • 2012-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多