在ruby中优雅地处理数据结构(哈希等)

时间:2009-11-16 19:47:08

标签: ruby data-structures hash dictionary

我最近做了一个课程作业,我做了一个非常hacky的数据结构。我最终使用嵌套哈希,这似乎是一个好主意,但很难迭代和管理。

我正在做一般事情,比如一个标签映射到映射到价格和类似东西的项目的哈希。但其中一些变得越来越复杂。

我知道rails使用了很多更优雅的符号等东西(我从不使用可耻的脸),我想知道如何优化它。例如,如果我有这样的嵌套哈希

 h["cool"][????][1.2]

是否有一种优雅的方式将这些价值拉出来?也许我只是这方面的新手,但我想在开始做更多事情之前先做好准备。也许我甚至在寻找一些不同的东西,比如混合数组/哈希等等。请让我知道!

4 个答案:

答案 0 :(得分:3)

您似乎需要考虑更严格地构建数据。尝试为您的商品创建一个类,其中包含价格等等,并且可能以您需要的方式组织它们。想想你想要什么,并以对你有意义的方式将信息放在结构中。当你需要扩展系统并发现你做不到时,现在还有三个月就会浪费时间。

是的,这将是相当多的工作,是的,这是值得的。

答案 1 :(得分:2)

编辑:修改为提供项目的粗略路径。它虽然无法知道变量的名称。

试试这个:

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!

答案 2 :(得分:0)

h["cool"].keys

然后迭代树将是

h["cool"].keys.each |outer| { h["cool"][outer].each { |inner| puts inner }}

答案 3 :(得分:0)

这实际上取决于你想要做什么(问题中没有足够的信息),但如果你需要在三个或更多级别潜入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是您尝试做的最佳数据结构吗?