如何在 Ruby 中实现查找类?
Posted
技术标签:
【中文标题】如何在 Ruby 中实现查找类?【英文标题】:How to implement a lookup class in Ruby? 【发布时间】:2014-12-07 02:45:01 【问题描述】:我有一个不可变值对象的列表。查找类提供了迭代和查询数据的方法:
class Banker
Bank = Struct.new(:name, :bic, :codes)
attr_reader :banks
def initialize
@banks = [
Bank.new('Citibank', '1234567', ['1', '2']),
Bank.new('Wells Fargo', '7654321', ['4']), # etc.
]
end
def find_by_bic(bic)
banks.each do |bank|
return bank if bank.bic == bic
end
end
end
@banks
在每次使用 Banker
时都会被初始化。有哪些选项可以缓存@banks
,以便在Banker
的不同实例中重复使用?
【问题讨论】:
我不明白投反对票的原因。我认为问题和问题得到了很好的解释。请详细说明缺少的内容! 这个问题对我来说很清楚,但可能投票者认为问题陈述本身有点宽泛(如果是这样的话,我不同意)。或者标题与您实际要求的内容不完全匹配(不是真正的否决理由imo)。 【参考方案1】:我不认为Struct
在这里给你买任何东西。这样做怎么样?
代码
class Banker
@all_banks =
class << self
attr_reader :all_banks
end
attr_reader :banks
def initialize(banks)
@banks = banks.keys
banks.each |k,v| self.class.all_banks[k] = v
end
def find_by_bic(bic)
return nil unless @banks.include?(bic)
self.class.all_banks[bic]
end
end
需要注意self.class
中的self
来区分self
的类和关键字class
。
示例
b1 = Banker.new( '1234567' => name: 'Citibank', codes: ["1", "2"] ,
'7654321' => name: 'Wells Fargo', codes: ['4'] )
b1.banks
#=> ["1234567", "7654321"]
Banker.all_banks
#=> "1234567"=>:name=>"Citibank", :codes=>["1", "2"],
# "7654321"=>:name=>"Wells Fargo", :codes=>["4"]
b1.find_by_bic '7654321'
#=> :name=>"Wells Fargo", :codes=>["4"]
b1.find_by_bic '1234567'
#=> :name=>"Citibank", :codes=>["1", "2"]
b1.find_by_bic '0000000'
#=> nil
b2 = Banker.new( '6523155' => name: 'Bank of America', codes: ["3"] ,
'1234567' => name: 'Citibank', codes: ["1", "2"] )
b2.banks
#=> ["6523155", "1234567"]
Banker.all_banks
#=> "1234567"=>:name=>"Citibank", :codes=>["1", "2"],
# "7654321"=>:name=>"Wells Fargo", :codes=>["4"],
# "6523155"=>:name=>"Bank of America", :codes=>["3"]
b2.find_by_bic '6523155'
#=> :name=>"Bank of America", :codes=>["3"]
b2.find_by_bic '1234567'
#=> :name=>"Citibank", :codes=>["1", "2"]
b2.find_by_bic '7654321'
#=> nil
替代品
如果您愿意,也可以添加类方法:
def self.new(banks)
banks.each |k,v| all_banks[k] = v
super
end
并删除initialize
中的第一行。
或者,如果您有所有银行的完整列表,您可以改为将 all_banks
设为常量:
ALL_BANKS = "1234567"=>:name=>"Citibank", :codes=>["1", "2"],
"7654321"=>:name=>"Wells Fargo", :codes=>["4"],
"6523155"=>:name=>"Bank of America", :codes=>["3"]
def find_by_bic(bic)
return nil unless @banks.include?(bic)
ALL_BANKS[bic]
end
并将initialize
更改为:
def initialize(bics)
@banks = bics
end
其中bics
是bic
值的数组。
【讨论】:
【参考方案2】:要在实例之间共享不可变数据,您可以使用冻结类变量:@@banks ||= [...].freeze
【讨论】:
以上是关于如何在 Ruby 中实现查找类?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Handsontable 中实现“查找和替换”逻辑?
ruby 本要点展示了我如何使用Ruby AWS SDK,Fog和Carrierwave在我的应用程序中实现AWS假设角色功能