Вложенный словарь навигации - PullRequest
0 голосов
/ 19 марта 2020

У меня есть вложенный словарь / ха sh структура в Ruby, например:

d = {
 :foo => {
   :hoo => nil,
   :baz => {
     # ...
   },
 },

 :bar => {
   :doo => { 
      # ...
   },
   :loo => nil, 
 },

 # ...
}

Каждый отдельный словарь имеет неизвестный размер. Его ключи являются символами, а его значения - либо nil, либо другой словарь. Я пытаюсь написать два метода:

  1. down() принимает текущий словарь и действительный ключ в качестве аргументов и возвращает указатель на это значение (либо ноль, либо другой словарь).
  2. up() берет текущий словарь и возвращает указатель на внешний словарь, в котором он содержится.

down() прост (это то же самое, что d[:foo]) , но я не решаюсь просто использовать d[:foo], поскольку up() в принципе невозможно без сохранения какой-либо дополнительной структурной / навигационной информации о d при вызове down().

Возвращаемые значения не могут быть копиями что-то в d, они должны быть указателями. Я все еще не понимаю, какие ситуации передаются по значению по сравнению с передачей по ссылке в Ruby, но я знаю, что все его переменные «эффективно указатель» являются изменяемыми.

Обновление :

Когда я говорю «берет текущий словарь», я просто ссылаюсь на некоторую переменную dict, такую ​​как dict = d или dict = (some child of d). dict - это словарь или ноль. Например:

d = # ...

dict = down(d, :foo)
# dict is now the current dictionary and points to {:hoo=>nil,:baz=>{}} in d

dict2 = down(dict, :baz)
# down() "takes the current dictionary" (dict) 
# then returns a new current dictionary (dict2)

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

1 Ответ

1 голос
/ 19 марта 2020

Я не уверен, что полностью понимаю вопрос, но, возможно, вы ищете что-то вроде следующего, который является просто связанным списком, а не вложенным ха sh словарей, но я думаю, что это более типично для того, что делается в Ruby.

class Dictionary
  attr_accessor :name, :up, :down
  def initialize(name, up)
    @name = name
    @up = up
    @down = []
    up.down << self unless up.nil?
  end
end

Мы начинаем с создания верхнего словаря.

top = Dictionary.new("top", nil)
  #=> #<Dictionary:0x000056dd361bcd48 @name="top", @up=nil, @down=[]>

Теперь давайте создадим дочерний элемент top.

top_foo = Dictionary.new("foo", top)
  #=> #<Dictionary:0x000056dd361ce458 @name="foo",
  #     @up=#<Dictionary:0x000056dd361bcd48 @name="top", @up=nil,
  #       @down=[#<Dictionary:0x000056dd361ce458 ...>]>,
  #     @down=[]>

Внимательно посмотрите на возвращаемое значение. Значение переменной экземпляра top_foo @up является экземпляром Dictionary с именем top. Мы можем увидеть это более четко следующим образом:

top_foo.up.name
  #=> "top"
top_foo.down
  #=> []

Давайте посмотрим, как изменился top.down (ранее пустой массив).

top.down.map(&:name)
  #=> ["foo"]

Теперь создайте другого потомка top .

top_goo = Dictionary.new("goo", top)
  #=> #<Dictionary:0x000056dd3611a480 @name="goo",
  #     @up=#<Dictionary:0x000056dd35eed180 @name="top",...
  #     @down=[]> 
top_goo.up.name
  #=> "top" 
top_goo.down
  #=> [] 

top.down.map(&:name)
  #=> ["foo", "goo"]

Теперь создайте дочерний элемент top_foo:

top_foo_who = Dictionary.new("who", top_foo)
  #=> #<Dictionary:0x000056dd36171488 @name="who",
  #     @up=#<top_foo instance>

top_foo_who.name
  #=> "who"
top_foo_who.up.name
  #=> "foo"
top_foo_who.down
  #=> []

top_foo.down.map(&:name)
  #=> "foo"

Предположим, что мы будем с sh до go с top_foo_who до top.

start = top_foo_who
dict = loop do
  break start if start.up.nil?
  start = start.up
end
  #=> #<Dictionary:...> 

dict.name
  #=> "top" 
dict.down.map(&:name)
  #=> ["foo", "goo"] 

Если бы мы хотели go от top до top_foo, то под именем "foo" мы могли бы написать:

idx = top.down.map(&:name).index("foo")
  #=> 0
dict = top.down[idx]      
  #=> #<Dictionary...>
dict.name
  #=> "foo"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...