代码之家  ›  专栏  ›  技术社区  ›  johncssjs

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

  •  2
  • johncssjs  · 技术社区  · 2 年前

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

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

    我希望输出是-

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

    我想迭代每个元素 split 穿上它 , 并以某种递归方式添加到临时哈希中,但我不知道如何将它们嵌套。

    2 回复  |  直到 2 年前
        1
  •  1
  •   Schwern    2 年前

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

    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
    
        2
  •  1
  •   Silvio Mayolo    2 年前

    这应该让你开始。

    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" => {}} 。这取决于您是否有意义,或者您是否希望获取遇到的“第一个”值,或者是否将所有这些值组成一个数组。由于问题中没有具体说明,我将把它作为练习留给读者。