如何在哈希对象中获取键

时间:2014-12-07 12:17:08

标签: ruby-on-rails ruby json hash trie

hash = {
  "d" => {
    "o" => {
      "g" => {
        "s" => {}
      },
      "l" => {
        "l" => {}
      },
      "o" => {
        "m" => {}
      }
    }
  },
  "b" => {
    "o"=>{
      "o"=>{
        "m"=>{}
      }
    }
  }
}

trie.print(hash)

在Trie类中,有一个名为print的方法可以打印trie

def print(trie)
  trie.each do |k,v|
    @res.concat(k)
    print(trie[k]) if trie[k].length > 0
    unless trie[k].length > 0 
      @result << @res unless trie[k].length > 0
      @res = ""
      p @result 
    end
  end
end

以上方法打印:

["dogs", "ll", "om", "boom"]

但我想打印:

["dogs" , "doll", "doom" , "boom"]

2 个答案:

答案 0 :(得分:2)

我认为我们不必传递前缀。

def compose(trie)
  trie.flat_map do |k, v|
    v.empty? ? k : compose(v).map{|sv| "#{k}#{sv}"}
  end      
end

答案 1 :(得分:0)

我已将该功能重命名为compose,以避免与Kernel#print发生冲突。原因是我从内部调用这个函数,它应该可以调用而不需要显式指向一个对象。您正在使用的方法不会“重用”遍历的前缀。最常见的方法是使用递归并在参数中构建该前缀。

我有这个递归功能。递归是处理树的常用方法。它接受一个“subtrie”和一个放在下面的前缀(默认为空字符串,如果没有给出)。递归基础:如果我们得到一个空的子集,我们返回一个构建前缀的单元素数组。较高级别将返回从给定“subtrie”构建的前缀数组。

def compose(trie, prefix="")
  trie.flat_map do |k, v|
    new_prefix = prefix + k
    results = compose(v, new_prefix)
    results.empty? ? new_prefix : results
  end
end

注意flat_map,否则(使用map)它将输出一个深层嵌套的数组,其结构为你的trie,并用生成的前缀替换了叶子。

UPD :新版本返回空子阵列的空数组。