在ruby中优雅地处理数据结构(哈希等)
我最近做了一个类的任务,我做了一个非常黑客的数据结构。我最终使用了嵌套散列,这似乎是一个好主意,但是很难遍历和管理。在ruby中优雅地处理数据结构(哈希等)
我在做一般的东西,就像一个标签映射到物品的散列,映射到价格和类似的东西。但其中一些变得越来越复杂。
我知道,铁轨使用了很多更优雅的看似东西与符号等(我从来没有使用可耻的脸),我想知道如何可以优化这一点。例如,如果我有我的嵌套散列这样的东西
h["cool"][????][1.2]
有没有一种优雅的方式拉出这些值?也许我只是这方面的一个新手,但我想在开始做更多事情之前设置好事情。也许我甚至在寻找不同的东西,比如数组/混编或其他东西。请告诉我!
h["cool"].keys
到然后循环树是
h["cool"].keys.each |outer| { h["cool"][outer].each { |inner| puts inner }}
当然,我正在做这样的事情,我想。但它非常麻烦,如果你需要多达5个嵌套数组呢? – 2009-11-16 20:41:07
@Stacia然后你写一个递归版本。 – EmFi 2009-11-16 21:13:31
看起来你需要考虑更严格的结构化数据。尝试为您的物品创建一个类,这些类可以包含其他物品的价格,也可以按照您访问它们的方式组织它们。想想你想要什么,并以一种对你有意义的方式将信息放置在结构中。如果您需要扩展系统并找不到,其他任何事情都会浪费时间,无论是现在还是三个月。
是的,这将是一个相当多的工作,是的,这将是值得的。
免责声明:抛出本季度的课程;) 如果我有时间或它在下一个任务上变得可怕,我可能会尝试类似的东西。 – 2009-11-16 20:42:20
红宝石纯粹是面向对象的。 Ruby中的类实际上并不像其他语言中的那么多。你可能会得到一个大部分为空的类和一个attr_accessors列表。 – EmFi 2009-11-16 21:15:06
甚至打开 – 2009-11-17 09:01:18
这实际上取决于你想要做什么(在问题中没有足够的信息),但是如果你需要潜入三个或更多级别到Hash
,你可能很想要一个递归树遍历算法:
def hash_traverse(hash)
result = ""
for key, value in hash
result << key.to_s + ":\n"
if !value.kind_of?(Hash)
result << " " + value.to_s + "\n"
else
result << hash_traverse(value).gsub(/^/, " ")
end
end
return result
end
你确定一个Hash
是你想要做什么是最好的数据结构?
修改:提供物品的粗略路径。它不能知道变量的名字。
试试这个:
def iterate_nested(array_or_hash, depth = [], &block)
case array_or_hash
when Array:
array_or_hash.each_with_index do |item, key|
if item.class == Array || item.class == Hash
iterate_nested(item, depth + [key], &block)
else
block.call(key, item, depth + [key])
end
end
when Hash:
array_or_hash.each do |key, item|
if item.class == Array || item.class == Hash
iterate_nested(item, depth + [key], &block)
else
block.call(key, item, depth + [key])
end
end
end
end
应该重复,以必要的深度,由存储器等的限制,并返回返回项目的重点和项目和深度。适用于哈希和数组。
如果用测试:
iterate_nested([[[1,2,3], [1,2,3]], [[1,2,3], [1,2,3]], [[1,2,3], [1,2,3]]]) do |key, item, depth|
puts "Element: <#{depth.join('/')}/#{key}> = #{item}"
end
它产生:
Element: <0/0/0/0> = 1
Element: <0/0/1/1> = 2
Element: <0/0/2/2> = 3
Element: <0/1/0/0> = 1
Element: <0/1/1/1> = 2
Element: <0/1/2/2> = 3
Element: <1/0/0/0> = 1
Element: <1/0/1/1> = 2
Element: <1/0/2/2> = 3
Element: <1/1/0/0> = 1
Element: <1/1/1/1> = 2
Element: <1/1/2/2> = 3
Element: <2/0/0/0> = 1
Element: <2/0/1/1> = 2
Element: <2/0/2/2> = 3
Element: <2/1/0/0> = 1
Element: <2/1/1/1> = 2
Element: <2/1/2/2> = 3
Cheerio!
这是一个有趣的问题要回答,谢谢你的提问。 :-) – 2009-11-16 21:14:05