Jak nazywa się ten Hash-like/Tree-like Construct?

Chcę stworzyć klasę" Config", która działa gdzieś pomiędzy Hashem a drzewem. Służy tylko do przechowywania wartości globalnych, które mogą mieć kontekst.

Oto jak go używam:

Config.get("root.parent.child_b") #=> "value"

Oto jak może wyglądać Klasa:

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

Czy jest jakaś nazwa dla tego typu rzeczy, gdzieś pomiędzy Hashem a drzewem (nie na kierunku Informatyka)? Zasadniczo interfejs podobny do hasha do drzewa.

Coś, co wychodzi tak:

t = TreeHash.new
t.set("root.parent.child_a", "value")
t.set("root.parent.child_b", "another value")

Pożądane wyjście format:

t.get("root.parent.child_a") #=> "value"
t.get("root") #=> {"parent" => {"child_a" => "value", "child_b" => "another value"}}

Zamiast tego:

t.get("root") #=> nil

Lub to (z którego otrzymujesz wartość wywołując {}.value)

t.get("root") #=> {"parent" => {"child_a" => {}, "child_b" => {}}}
Author: Lance Pollard, 2010-06-05

5 answers

Możesz zaimplementować jeden w krótkim czasie:

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

Możesz poprawić implementację, ustawiając niepotrzebne metody Hash jako prywatne, ale już działa tak, jak tego chciałeś. Dane są przechowywane w hash, dzięki czemu można je łatwo przekonwertować na yaml.


EDIT:

Aby spełnić dalsze oczekiwania (i, domyślnie poprawnie Konwertuj to_yaml) należy użyć zmodyfikowanej wersji:

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

Ta wersja jest lekka kompromis, ponieważ nie można przechowywać wartości w non-leaf węzły.

 8
Author: samuil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-06 08:27:31

Myślę, że nazwa struktury jest tak naprawdę zagnieżdżonym Hashem , A kod w pytaniu jest ponownym opracowaniem słowników javascript. Od słownika w JS (lub Pythona lub ...) może być zagnieżdżony, każda wartość może być innym słownikiem, który ma swoje własne pary klucz / val. W javascript to wszystko, czym jest obiekt.

A najlepszym bitem jest możliwość użycia JSON, aby je dokładnie zdefiniować i przekazać:

tree : {
  'root' : {
    'parent' : {
      'child_a' : "value",
      'child_b' : "another value"
    },
    'another_parent' : {
      'something' : {
        'nesting' : "goes on and on"
      }
    }
  }
};

W JS możesz wtedy zrobić drzewo.root.rodzic.child_a.

Ta odpowiedź na inne pytanie sugeruje użycie hashie gem do konwersji obiektów JSON w Obiekty Ruby.

 1
Author: Phil H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:52:17

Wydaje mi się, że przypomina to strukturę danych mapy drzewa podobną do tej opisanej w Javie tutaj. Robi to samo (mapowanie klucza/wartości), ale pobieranie może być inne, ponieważ używasz samych węzłów jako kluczy. Pobieranie z opisanej mapy drzewa jest pobierane z implementacji, ponieważ kiedy przekazujesz klucz, nie znasz dokładnej lokalizacji w drzewie.

Mam nadzieję, że to ma sens!

 0
Author: Kryptic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-05 06:18:44

Er... z pewnością można to zrobić, używając hierarchicznej tabeli hash, ale po co Ci hierarchia? Jeśli potrzebujesz tylko dokładnie dopasowującego get I put, dlaczego nie możesz po prostu utworzyć jednej tabeli hash, która używa konwencji nazewnictwa oddzielonej kropkami?

To wszystko, co jest potrzebne, aby zaimplementować funkcjonalność, o którą prosiłeś, i jest to oczywiście bardzo proste...

 0
Author: Cypherpunks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-05 07:47:09

Po co w ogóle używać interfejsu haszującego? Dlaczego nie użyć łączenia metod do poruszania się po drzewie? Na przykład {[0] } i używać metod instancji, a w razie potrzeby method_missing() do ich implementacji?

 0
Author: mataal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-02 05:37:31