我有一组嵌套的哈希,这些哈希提供了一组定义应用程序行为的参数:
custom_demo_options: {
verticals: {
fashion: true,
automotive: false,
fsi: false
},
channels: {
b2b: true,
b2c: true
}
}
website_data: {
verticals: {
fashion: {
b2b: {
code: 'luma_b2b',
url: 'b2b.luma.com'
},
b2c: {
code: 'base',
url: 'luma.com'
}
}
}
}
custom_demo_options
哈希中的选择与website_data
哈希中存储的数据有关,并从中返回值:
data = []
collection = {}
custom_demo_options[:verticlas].each do |vertical_name, vertical_choice|
# Get each vertical selection
if vertical_choice == true
# Loop through the channels for each selected vertical
custom_demo_options[:channels].each do |channel_name, channel_choice|
# Get each channel selection for each vertical selection
if channel_choice == true
# Loop through the website data for each vertical/channel selection
website_data[:verticals].each do |site_vertical, vertical_data|
# Look at the keys of the [:website_data][:verticals] hash
# If we have a vertical selection that matches a website_data vertical...
if site_vertical == vertical_name
# For each website_data vertical collection...
vertical_data.each do |vertical_channel, channel_value|
# If we have a matching channel in the collection...
if vertical_channel == channel_name
# Add the channel's url and code to the collection hash
collection[:url] = channel_value[:url]
collection[:code] = channel_value[:code]
# Push the collection hash(es) onto the data array
data.push(collection)
}
}
}
}
}
}
}
}
推送到数据数组的数据最终用于创建以下nginx映射定义:
map $http_host $MAGE_RUN_CODE {
luma.com base;
b2b.luma.com luma_b2b;
}
作为散列之间关系的示例,如果用户设置custom_demo_options[:channels][:b2b] to
false, the b2b code/url pair stored in the
website_data`哈希将从nginx块中移除:
map $http_host $MAGE_RUN_CODE {
luma.com base;
}
上面的代码有效,但是我知道它效率极低。我对红宝石比较陌生,但我认为这很可能是逻辑上的挑战,而不是特定于语言的挑战。
我的问题是,连接这些哈希而不是像我之前那样使用循环的正确方法是什么?我已经对hash.select
进行了一些阅读,看来这可能是最好的方法,但是我想知道:还有其他我应该考虑的方法可以优化此操作吗?
假设您有key = :foo
和hash = { foo: 1, bar: 2 }
-您想知道该键的哈希值。
您在这里使用的方法本质上是
result = nil
hsh.each { |k,v| result = v if k == :foo }
但是为什么可以这样说呢?>
result = hsh[:foo]
似乎您了解散列如何成为可迭代的结构,并且可以像数组一样遍历它们。但是您做得太过分了,而忘记了哈希是索引结构。就您的代码而言,我将这样重构:
。# fixed typo here: verticlas => verticals custom_demo_options[:verticals].each do |vertical_name, vertical_choice| # == true is almost always unnecessary, just use a truthiness check next unless vertical_choice custom_demo_options[:channels].each do |channel_name, channel_choice| next unless channel_choice vertical_data = website_data[:verticals][site_vertical] channel_value = vertical_data[channel_name] # This must be initialized here: collection = {} collection[:url] = channel_value[:url] collection[:code] = channel_value[:code] data.push(collection) end end
您会看到许多嵌套和复杂性已被删除。请注意,我在初始化
collection
时添加了属性。这里要介绍的内容太多了,但我强烈建议您阅读Ruby中的可变性。您当前的代码可能无法实现预期的效果,因为您将相同的collection
哈希多次推入数组中
此时,您可以将其重构为更具功能性的编程样式,并使用一些链接的方法,但是我会把这个练习留给您