我想创建一个在散列和树之间起作用的“Config”类。它只是用于存储全局值,它可以具有上下文。
以下是我如何使用它:
Config.get("root.parent.child_b") #=> "value"
以下是该课程的样子:
class Construct
def get(path)
# split path by "."
# search tree for nodes
end
def set(key, value)
# split path by "."
# create tree node if necessary
# set tree value
end
def tree
{
:root => {
:parent => {
:child_a => "value",
:child_b => "another value"
},
:another_parent => {
:something => {
:nesting => "goes on and on"
}
}
}
}
end
end
Hash和Tree(不是计算机科学专业)之间是否有这种名称的名称?基本上是树的类似哈希的接口。
像这样输出的东西:
t = TreeHash.new
t.set("root.parent.child_a", "value")
t.set("root.parent.child_b", "another value")
所需的输出格式:
t.get("root.parent.child_a") #=> "value"
t.get("root") #=> {"parent" => {"child_a" => "value", "child_b" => "another value"}}
而不是:
t.get("root") #=> nil
或者这(通过调用{}.value
获得价值)
t.get("root") #=> {"parent" => {"child_a" => {}, "child_b" => {}}}
答案 0 :(得分:9)
您可以在任何时间实施一个:
class TreeHash < Hash
attr_accessor :value
def initialize
block = Proc.new {|h,k| h[k] = TreeHash.new(&block)}
super &block
end
def get(path)
find_node(path).value
end
def set(path, value)
find_node(path).value = value
end
private
def find_node(path)
path.split('.').inject(self){|h,k| h[k]}
end
end
您可以通过将不需要的Hash
方法设置为私有方法来改进实现,但它已经按照您希望的方式工作。数据存储在哈希中,因此您可以轻松地将其转换为yaml。
<小时/> 修改强>
为了满足进一步的期望(并且默认情况下正确转换to_yaml
),您应该使用修改后的版本:
class TreeHash < Hash
def initialize
block = Proc.new {|h,k| h[k] = TreeHash.new(&block)}
super &block
end
def get(path)
path.split('.').inject(self){|h,k| h[k]}
end
def set(path, value)
path = path.split('.')
leaf = path.pop
path.inject(self){|h,k| h[k]}[leaf] = value
end
end
此版本略有权衡,因为您无法在非叶子节点中存储值。
答案 1 :(得分:1)
我认为结构的名称实际上是嵌套哈希,问题中的代码是javascript词典的重新发明。由于JS(或Python或...)中的字典可以嵌套,因此每个值可以是另一个字典,它具有自己的键/值对。在javascript中,这都是一个对象。
最好的一点是能够使用JSON整齐地定义它并传递它:
tree : {
'root' : {
'parent' : {
'child_a' : "value",
'child_b' : "another value"
},
'another_parent' : {
'something' : {
'nesting' : "goes on and on"
}
}
}
};
在JS中,您可以执行tree.root.parent.child_a。
This answer to another question建议使用Hashie gem将JSON对象转换为Ruby对象。
答案 2 :(得分:0)
我认为这类似于一个类似于Java描述的here的TreeMap数据结构。它执行相同的操作(键/值映射),但检索可能会有所不同,因为您使用节点本身作为键。从描述的TreeMap中检索是从实现中抽象出来的,因为当你传入一个键时,你不知道它在树中的确切位置。
希望有意义!
答案 3 :(得分:0)
呃......当然可以使用分层哈希表来完成,但为什么需要层次结构呢?如果您只需要精确匹配的get和put,为什么不能只使用一个使用点分隔命名约定的哈希表?
这就是实现您所要求的功能所需要的,而且显然非常简单......
答案 4 :(得分:0)
为什么要使用类似哈希的界面?为什么不使用链接方法来导航树?例如config.root.parent.child_b
并使用实例方法,如果需要method_missing()
来实现它们?