Чем Называют эту Конструкцию Hash-like/Tree-like?

Я хочу создать класс "Конфигурации", который действует где-нибудь между хешем и деревом. Только для хранения глобальных значений, может иметь контекст.

Вот то, как я использую его:

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)

t.get("root") #=> {"parent" => {"child_a" => {}, "child_b" => {}}}
6
задан Lance Pollard 5 June 2010 в 23:37
поделиться

4 ответа

Вы можете реализовать его в кратчайшие сроки:

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.


РЕДАКТИРОВАТЬ:

Чтобы оправдать дальнейшие ожидания (и правильно преобразовать в_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

Эта версия представляет собой небольшой компромисс, так как вы не можете хранить значения в нелистовые узлы.

9
ответ дан 10 December 2019 в 00:34
поделиться

Э... это, конечно, можно сделать, используя иерархическую хэш-таблицу, но зачем вам нужна иерархия? Если вам нужны только точно совпадающие get и put, почему вы не можете просто сделать одну хэш-таблицу, которая использует соглашение об именовании с разделителями точек?

Это все, что нужно для реализации функциональности, о которой вы просили, и это, очевидно, очень просто...

0
ответ дан 10 December 2019 в 00:34
поделиться

Я думаю, что это напоминает структуру данных TreeMap, аналогичную той, что описана в Java здесь . Он делает то же самое (сопоставление ключей и значений), но извлечение может быть другим, поскольку вы используете сами узлы в качестве ключей. Получение из описанного TreeMap абстрагируется от реализации, поскольку, когда вы передаете ключ, вы не знаете его точное местоположение в дереве.

Надеюсь, это имеет смысл!

0
ответ дан 10 December 2019 в 00:34
поделиться

Зачем вообще использовать хеш-подобный интерфейс? Почему бы не использовать цепочку методов для навигации по дереву? Например, config.root.parent.child_b и использовать методы экземпляра и, если необходимо, method_missing () для их реализации?

0
ответ дан 10 December 2019 в 00:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: