Ruby 这个类似散列/树的构造叫什么?

Ruby 这个类似散列/树的构造叫什么?,ruby,hash,tree,computer-science,construct,Ruby,Hash,Tree,Computer Science,Construct,我想创建一个“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

我想创建一个“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
这种东西有没有名字,介于散列和树之间(不是计算机科学专业)?基本上是一个类似散列的树接口

输出如下所示的内容:

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
从中获取值)


我认为这类似于一个树状图数据结构,类似于Java中描述的数据结构。它做同样的事情(键/值映射),但是检索可能不同,因为您使用节点本身作为键。从描述的树映射中检索是从实现中抽象出来的,因为当您传入一个键时,您不知道它在树中的确切位置


希望这有意义

呃。。。当然可以使用分层哈希表来完成,但是为什么需要分层呢?如果您只需要精确匹配get和put,为什么不能创建一个恰好使用点分隔命名约定的哈希表呢


这就是实现您所要求的功能所需的全部,而且显然非常简单…

为什么要使用类似散列的接口?为什么不使用方法链来导航树?例如
config.root.parent.child\u b
并使用实例方法,如果需要
method\u missing()
来实现它们

您可以立即实现一个:

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

这个版本有点折衷,因为您不能在非叶节点中存储值。

我认为该结构的名称实际上是一个嵌套哈希,问题中的代码是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


建议使用将JSON对象转换为Ruby对象。

我希望能够使用yaml定义所有这些,并能够在任何级别检索子节点,但同时能够将其存储在数据库中,并让最终用户对其进行自定义。所以它最终是一棵树不?太复杂了,我希望任何有经验的人都能使用它。使用点分隔字符串的散列很容易理解。嵌套对象/类更复杂,也更难为新手定制。有没有办法添加a)这样叶节点就不是散列,而是值(这基本上意味着删除
attr\u访问器:value
),b)这样
get(“root”)
或者任何级别如果不是叶节点,都会返回下面的树而不是null?试图实现它,但它增加了很多代码/复杂性,也许你知道一些单行程序技巧。我已经用示例输出更新了这个问题。嗨,这太棒了,应该包含在Ruby core中!但是,使用第二个实现,在非叶节点上,我在yaml输出中得到“!ruby/hash:TreeHash”。是否有任何非gsub的方法来删除此项?谢谢
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
tree : {
  'root' : {
    'parent' : {
      'child_a' : "value",
      'child_b' : "another value"
    },
    'another_parent' : {
      'something' : {
        'nesting' : "goes on and on"
      }
    }
  }
};