Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 从密钥数组递归设置哈希密钥_Arrays_Ruby_Ruby Hash - Fatal编程技术网

Arrays 从密钥数组递归设置哈希密钥

Arrays 从密钥数组递归设置哈希密钥,arrays,ruby,ruby-hash,Arrays,Ruby,Ruby Hash,我想要一个函数,它可以接受像[:a,:b,:c]这样的数组,并递归地设置散列键,在运行时创建所需的内容 hash = {} hash_setter(hash, [:a, :b, :c], 'value') hash #=> {:a => {:b => {:c => 'value' } } } hash_setter(hash, [:a, :b, :h], 'value2') hash #=> {:a => {:b => {:c => 'va

我想要一个函数,它可以接受像
[:a,:b,:c]
这样的数组,并递归地设置散列键,在运行时创建所需的内容

hash = {}

hash_setter(hash, [:a, :b, :c], 'value') 
hash #=> {:a => {:b => {:c => 'value' } } }

hash_setter(hash, [:a, :b, :h], 'value2') 
hash #=> {:a => {:b => {:c => 'value', :h => 'value2' } } }
我知道Ruby 2.3的
dig
可以用于这种方式,尽管这并不能让你得到一个答案。如果有一个二传手相当于挖,这将是我正在寻找的

def set_value_for_keypath(initial, keypath, value)
    temp = initial

    for key in keypath.first(keypath.count - 1)
        temp = (temp[key] ||= {})
    end

    temp[keypath.last] = value

    return initial
end

initial = {:a => {:b => {:c => 'value' } } }

set_value_for_keypath(initial, [:a, :b, :h], 'value2')

initial
或者,如果您更喜欢不可读的内容:

def set_value_for_keypath(initial, keypath, value)
    keypath.first(keypath.count - 1).reduce(initial) { |hash, key| hash[key] ||= {} }[keypath.last] = value
end
代码

def nested_hash(keys, v, h={})
  return subhash(keys, v) if h.empty?
  return h.merge(subhash(keys, v)) if keys.size == 1
  keys[0..-2].reduce(h) { |g,k| g[k] }.update(keys[-1]=>v)
  h
end

def subhash(keys, v)
  *first_keys, last_key = keys
  h = { last_key=>v }
  return h if first_keys.empty?
  first_keys.reverse_each.reduce(h) { |g,k| g = { k=>g } }
end
示例

h = nested_hash([:a, :b, :c], 14)    #=> {:a=>{:b=>{:c=>14}}}
i = nested_hash([:a, :b, :d], 25, h) #=> {:a=>{:b=>{:c=>14, :d=>25}}}
j = nested_hash([:a, :b, :d], 99, i) #=> {:a=>{:b=>{:c=>14, :d=>99}}}
k = nested_hash([:a, :e], 104, j)    #=> {:a=>{:b=>{:c=>14, :d=>99}, :e=>104}}
    nested_hash([:f], 222, k)        #=> {:a=>{:b=>{:c=>14, :d=>99}, :e=>104}, :f=>222}
观察
:d
的值在计算
j
时被覆盖。还请注意:

subhash([:a, :b, :c], 12)
  #=> {:a=>{:b=>{:c=>12}}}
这会使散列
h
发生变异。如果不需要,可以插入该行

  f = Marshal.load(Marshal.dump(h))

行之后,如果h为空,则返回subhash(键,v)
,并将后续对
h
的引用更改为
f
。模块中的方法可用于创建散列的深度副本,以便原始散列不会发生变异。

使用递归解决它:

def hash_setter(hash, key_arr, val)
  key = key_arr.shift
  hash[key] = {} unless hash[key].is_a?(Hash)
  key_arr.length > 0 ? hash_setter(hash[key], key_arr, val) : hash[key] = val
end

你为什么想要这个?o、 0'我正在将父->子关系从数组映射到哈希。第一个参数的作用是什么?我真的不明白你的目的是什么“寻找最短、最优雅的答案”-基于意见的问题。“内置或一行”-对不起,我通常不会对这些东西发表评论,但你已经用两句话触发了我4次…@naomik按照这些标准,这应该在codegolf.stackexchange.com上