【问题标题】:How to optimize mapping hash that contains similar keys and values?如何优化包含相似键和值的映射哈希?
【发布时间】:2020-11-28 08:55:37
【问题描述】:

我有一些像这样定义的常量

CONSUMER_TYPE = 'consumer'
CONSUMER_1_TYPE = "#{CONSUMER_TYPE}1"
CONSUMER_2_TYPE = "#{CONSUMER_TYPE}2"
CONSUMER_3_TYPE = "#{CONSUMER_TYPE}3"

INDUSTRIAL_TYPE = 'industrial'
INDUSTRIAL_1_TYPE = "#{INDUSTRIAL_TYPE}1"
INDUSTRIAL_2_TYPE = "#{INDUSTRIAL_TYPE}2"
INDUSTRIAL_3_TYPE = "#{INDUSTRIAL_TYPE}3"

SERVICES_TYPE = 'services'
SERVICES_1_TYPE = "#{SERVICES_TYPE}1"
SERVICES_2_TYPE = "#{SERVICES_TYPE}2"
SERVICES_3_TYPE = "#{SERVICES_TYPE}3"

记录字段的值可以是services2industrial1。在我的模型中,我创建了一个映射方法,该方法应该根据记录字段值返回具有不同属性集的哈希,如下所示

def classification_attributes
  product_type_mapping[product_type]
end

def product_type_mapping
  {
     CONSUMER_1_TYPE => { abc: abc, vpn: vpn, lbc: lbc },
     CONSUMER_2_TYPE => { abc: abc, vpn: vpn, lbc: lbc },
     CONSUMER_3_TYPE => { abc: abc, vpn: vpn, lbc: lbc },
     INDUSTRIAL_1_TYPE => { vpn: vpn, htt: htt, bnn: bnn },
     INDUSTRIAL_2_TYPE => { vpn: vpn, htt: htt, bnn: bnn },
     INDUSTRIAL_3_TYPE => { vpn: vpn, htt: htt, bnn: bnn },
     SERVICES_1_TYPE => { dhy: dhy, rtt: rtt, abc: abc },
     SERVICES_2_TYPE => { dhy: dhy, rtt: rtt, abc: abc },
     SERVICES_3_TYPE => { dhy: dhy, rtt: rtt, abc: abc }
  }
end

例如,如果记录包含值consumer3,则映射方法应返回{ abc: abc, vpn: vpn, lbc: lbc }。如您所见,有很多代码重复。我想知道是否有更优化、更简洁的方法来处理这项任务。

【问题讨论】:

  • 你选好了钥匙吗?为什么classification_attributes 不接受争论?
  • 然后我将classification_attributes 哈希与主要的base_attributes 合并。 base_attributes.merge(classification_attributes)

标签: ruby-on-rails ruby ruby-hash


【解决方案1】:
  1. 使用符号代替常量。
  2. 不要公开映射。

Ruby 中的常量主要用于信息隐藏。例如,如果密钥从consumer1 更改为consumer_1,只要所有内容都使用CONSUMER_1_TYPE 访问哈希,您就可以了。为什么要冒险?

相反,完全隐藏哈希。现在它被隐藏了,常量就不是必需的了。使用符号。

如果所有值都相同,请将它们放入各自的方法中。

def classification_attributes(product_type)
  product_type_mapping[product_type]
end

private def consumer_config
  { abc: abc, vpn: vpn, lbc: lbc }
end

private def industrial_config
  { vpn: vpn, htt: htt, bnn: bnn }
end

private def services_config
  { dhy: dhy, rtt: rtt, abc: abc }
end

private def product_type_mapping
  {
     conumser1: consumer_config,
     consumer2: consumer_config,
     consumer3: consumer_config,
     industrial1: industrial_config,
     industrial2: industrial_config,
     industrial3: industrial_config,
     services1: services_config,
     services2: services_config,
     services3: services_config
  }
end

在没有更多上下文的情况下,我可以这么说。如果有那么多冗余,您可以将product_type 拆分为类型和子类型。


考虑将product_type_mapping 移动到 config/application.rb 以及任何其他相关配置。这将应用程序配置保存在一个地方,而不是分散在各个类中。

module YourApp
  class Application < Rails::Application
    config.x.consumer_config = { abc: abc, vpn: vpn, lbc: lbc }.freeze
    config.x.industrial_config = { vpn: vpn, htt: htt, bnn: bnn }.freeze
    config.x.services_config = { dhy: dhy, rtt: rtt, abc: abc }.freeze

    config.x.product_type_mapping = {
      conumser1: config.x.consumer_config,
      consumer2: config.x.consumer_config,
      consumer3: config.x.consumer_config,
      industrial1: config.x.industrial_config,
      industrial2: config.x.industrial_config,
      industrial3: config.x.industrial_config,
      services1: config.x.services_config,
      services2: config.x.services_config,
      services3: config.x.services_config
    }.freeze
  end
end

# in your class...

def classification_attributes(product_type)
  Rails.configuration.x.product_type_mapping[product_type]
end

【讨论】:

  • 谢谢。我选择钥匙,所以consumer1consumer_1 的转换是不可能的。
猜你喜欢
  • 1970-01-01
  • 2015-12-26
  • 2017-10-13
  • 2013-11-23
  • 2011-01-08
  • 2016-09-15
  • 2018-11-13
  • 2018-06-10
  • 1970-01-01
相关资源
最近更新 更多