[英]How to further refactor a ruby hash
I'm writing a function that takes a string and returns a corresponding model class. 我正在编写一个函数,它接受一个字符串并返回一个相应的模型类。 The old version consists of ugly case statements, and the refactored version has a less-ugly hash.
旧版本包含丑陋的case语句,重构版本的哈希值较低。 However the hash still feels repetitive to me.
然而哈希仍然感觉重复我。 Could you give me some advice?
你能给我一些建议吗?
# original function
def determine_node_label(category)
label =
case category
when 'boundary box'
Slide
when 'circle', 'rectangle'
GroupBox
when 'text'
Text
when 'picture', 'pie', 'bar' , 'trend', 'star'
Content
else
Content
end
return label
end
# refactored function
def determine_node_label(category)
label = {
"boundary box" => Slide,
"circle" => GroupBox,
"rectangle" => GroupBox,
"text" => Text,
"picture" => Content,
"pie" => Content,
"bar" => Content,
"trend" => Content,
"star" => Content
}
label.default = Content
return label["category"]
end
update: 更新:
I would be more interested in solutions that assume that the label.default
is subject to change. 我会对假设
label.default
可能发生变化的解决方案更感兴趣。 My apologies for not making this clear in the code. 我很抱歉没有在代码中说清楚。
What about this? 那这个呢?
LABELS = {
"boundary box" => Slide,
"circle" => GroupBox,
"rectangle" => GroupBox,
"text" => Text
}
def determine_node_label(category)
LABELS[category] || Content
end
If you do want the dynamic default value, you can use Hash.fetch
. 如果确实需要动态默认值,可以使用
Hash.fetch
。 Also, pass the default value as the method parameter. 另外,将默认值作为方法参数传递。
LABELS = {
"boundary box" => Slide,
"circle" => GroupBox,
"rectangle" => GroupBox,
"text" => Text
}
def determine_node_label(category, default = 'Content')
LABELS.fetch(category, default)
end
For ease of maintainability I suggest the data be maintained in the following hash. 为了便于维护,我建议将数据保存在以下哈希中。
DATA = {
%w| boundary\ box | => 'Slide',
%w| circle rectangle | => 'GroupBox',
%w| text | => 'Text',
%w| picture pie bar trend star | => 'Content'
}
#=> {["boundary box"]=>"Slide", ["circle", "rectangle"]=>"GroupBox",
# ["text"]=>"Text", ["picture", "pie", "bar", "trend", "star"]=>"Content"}
Note that I made the values literals (strings) to demonstrate how this hash will be manipulated. 请注意,我创建了值literals(字符串)来演示如何操作此哈希。 In the actual application the values would not necessarily be literals.
在实际应用中,值不一定是文字。
Then provide a method to create the desired hash h
from DATA
and a specified default value (the latter to be returned by h[k]
when h
does not have a key k
). 然后提供一种从
DATA
和指定的默认值创建所需散列h
的方法(当h
没有密钥k
时,后者由h[k]
返回)。
def data_to_hash(data, default)
data.each_with_object({}) { |(k,v),h| k.each { |obj| h[obj] = v } }.
tap { |h| h.default = default }
end
This might be used as follows. 这可以如下使用。
h = data_to_hash(DATA, 'Cat')
#=> {"boundary box"=>"Slide", "circle"=>"GroupBox",
# "rectangle"=>"GroupBox", "text"=>"Text", "picture"=>"Content",
# "pie"=>"Content", "bar"=>"Content", "trend"=>"Content",
# "star"=>"Content"}
h["boundary box"]
#=> "Slide"
h["pie"]
#=> "Content"
h["cake"]
#=> "Cat"
To subsequently change the default you could either call data_to_hash
again, with the revised default, or simply execute 要随后更改默认值,您可以使用修订后的默认值再次调用
data_to_hash
,或者只是执行
h.default = "Dog"
or wrap the latter in a method. 或者将后者包装在一个方法中。
def change_default(h, new_default)
h.default = new_default
end
change_default(h, "Dog")
#=> "Dog"
h["pie"]
#=> "Content"
h["cake"]
#=> "Dog"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.