ruby - 嵌套字典导航
问题描述
我在 Ruby 中有一个嵌套的字典/哈希结构,如下所示:
d = {
:foo => {
:hoo => nil,
:baz => {
# ...
},
},
:bar => {
:doo => {
# ...
},
:loo => nil,
},
# ...
}
每个单独的字典的大小都未知。它的键是符号,它的值是或者是nil
另一个字典。我正在尝试编写两种方法:
down()
将当前字典和有效键作为参数并返回指向该值的指针(nil 或另一个字典)。up()
获取当前字典并返回指向它所在的外部字典的指针。
down()
很简单(它与 相同d[:foo]
),但我很犹豫是否只使用d[:foo]
,因为如果不存储一些关于as的up()
额外结构/导航信息,基本上是不可能的。d
down()
返回值不能是 中任何内容的副本d
,它们必须是指针。我仍然对 Ruby 中哪些情况是按值传递与按引用传递感到困惑,但我确实知道它的所有“有效指针”变量都是可变的。
更新:
当我说“使用当前字典”时,我只是指一些变量dict
,例如dict = d
or dict = (some child of d)
。dict
是字典或 nil。例如:
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)
在我尝试解决方案时,一些额外的实体跟踪当前字典所在的级别似乎很重要。
解决方案
我不确定我是否完全理解了这个问题,但也许您正在寻找类似以下的内容,它只是一个链表,而不是字典的嵌套哈希,但我认为这更典型地体现在 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"
假设我们希望从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"]
如果我们想从top
到top_foo
,按名称"foo"
,我们可以这样写:
idx = top.down.map(&:name).index("foo")
#=> 0
dict = top.down[idx]
#=> #<Dictionary...>
dict.name
#=> "foo"
推荐阅读
- react-native - 一些文本隐藏在我的验证屏幕的末尾。我如何在 react-native 中解决这个问题
- c# - 无法使用 GstSharp Nuget 包运行 c# 代码
- apache-spark - PySpark 中每组的滚动相关性和平均值(最后 3 个)
- powershell - 比较文件中两行的日期、日期、时间戳并输出最新的日期、日期、时间戳
- javascript - 如何将 SHA-256 Java 转换为 JavaScript(带有 NPM 的 IONIC)?
- ios - UIFont:如何使用文体替代字符?
- excel - 如何将 Excel 文件中的数据导入 PostgreSQL?
- php - 如何使用 PHP Ajax 编辑引导标记字段标记数据?
- math - 在不同方向的 3D 空间中定义宽度、高度、长度?
- github - 伙计们,github存储库中的“.yaml”文件和“.bat”文件在哪里?