将数组转换为每个元素的嵌套哈希

Convert array into nested hash for each element

我有一个这样的字符串数组,每个字符串用逗号分隔。它们可以按任何顺序排列。我想从中构建一个嵌套的哈希。如果一个项目已经存在,则应该嵌套后续元素。示例:

["a", "a,b", "d", "d,e", "d,e,f", "a,b,foobar"]

我希望输出为 -

  {
    a => {
      b => foobar
    },
    d => {
      e => f
    }
  }

我想遍历每个元素,然后 split 它在 , 上并以某种递归方式添加到临时哈希,但我不知道如何嵌套它们.

这应该可以帮助您入门。

def hashify(arr)
  # Get the first character from everything and make the hash.
  prefixes = arr.group_by { |x| x[0] }

  prefixes.transform_values do |inner|
    # Exclude the value that's just "a", i.e. that just shows the key
    # and no values inside.
    values = inner.map { |x| x[2..] }.grep_v(nil)
    # Recursively hashify the subvalues.
    hashify values
  end

end

给定输入

["a", "a,b", "d", "d,e", "d,e,f"]

这将产生

{"a"=>{"b"=>{}}, "d"=>{"e"=>{"f"=>{}}}}

请注意,这并非您想要的。即,"b" 已替换为 {"b" => {}}"f" 也是如此。目前还不清楚你想如何进行这种转变。例如,如果输入是

["a,b", "a,c"]

那么密钥 a 在生成的散列中应该映射到什么?在我上面的函数中,它将映射到散列 {"b" => {}, "c" => {}}。这是否有意义取决于您,或者您是否想要获取“第一个”遇到的值,或者可能制作所有这些值的数组。由于问题中没有具体说明,我将把它留作 reader.

的练习

首先,一个循环遍历数组并将这些字符串拆分为一个更易于使用的数组的函数。

def nest_array(array)
  return array.each_with_object({}) do |string, hash|
    values = string.split(/,/)

    do_nesting(values, hash)
  end
end

然后一个递归函数来处理每个单独的条目。 ['a'] 变为 { 'a' => nil }['a', 'b'] 变为 { 'a' => 'b' } 并且 ['a', 'b', 'c'] 递归以从 ['b', 'c'].

生成新的散列
def do_nesting(values, hash)
  if values.size <= 2
    hash[values[0]] = values[1]
  else
    hash[values.shift] = do_nesting(values, {})
  end

  return hash
end