Arrays 如何将数组转换为具有指定公共值的哈希
我有一个数组:Arrays 如何将数组转换为具有指定公共值的哈希,arrays,ruby,hash,Arrays,Ruby,Hash,我有一个数组:arr=[:a,:b,:c] 我想要一个散列,其中上面的每个值都是一个键,其值为空散列:hsh={a:{},b:{},c:{} 最简洁的方法是什么(是否存在性能权衡) 以下是我当前的解决方案: arr.inject({}) do |hash, entry| hash[entry] = {} hash end 有很多方法,例如: arr.zip([{}] * arr.size).to_h 或者(后者thx@Stefan可能不是您想要的,因为它将为所有密钥共享一个哈希):
arr=[:a,:b,:c]
我想要一个散列,其中上面的每个值都是一个键,其值为空散列:hsh={a:{},b:{},c:{}
最简洁的方法是什么(是否存在性能权衡)
以下是我当前的解决方案:
arr.inject({}) do |hash, entry|
hash[entry] = {}
hash
end
有很多方法,例如:
arr.zip([{}] * arr.size).to_h
或者(后者thx@Stefan可能不是您想要的,因为它将为所有密钥共享一个哈希):
一种方法是使用
每个:
hsh = {}
arr.each {|x| hsh[x] = {}}
- +表达你想要的东西
- +不会创建合并到一个哈希中的多个对
- +懒惰-可以立即使用/不会为未使用的钥匙浪费内存
- -Lazy-如果修改了
arr
,如果尚未访问初始可用密钥,也将修改它们
- -每次要访问新密钥时,都在数组中执行线性搜索
Hash.new { |hash, key| hash[key] = {} if arr.include? key }
您可以使用而不是inject
来避免返回值:
arr.each_with_object({}) { |k, h| h[k] = {} }
#=> {:a=>{}, :b=>{}, :c=>{}}
在中隐藏了一个较短的方法,但Cary不推荐;-) 我想出了两个技巧
技术1
p Hash[arr.dup.fill{ |i| [arr[i], {}]}] # preserves original arr, works on copy (dup)
p Hash[arr.fill{ |i| [arr[i], {}]}] # mutates original arr
技术2
arr = [:a, :b, :c]
p Hash[arr.zip(Array.new(arr.length) { |i| i = {}})]
技术3-这是技术2的一个变体,使用Ruby 2.1中可用的方法
p [:a, :b, :c].instance_eval { self.zip(Array.new(self.length) {|i| i = {}})}.to_h
所有上述技术都将产生所需的输出
{:a=>{}, :b=>{}, :c=>{}}
这将返回一个散列数组,而不是相同的。编辑后生成散列而不是数组。是的,一旦确定他们想要的是散列而不是数组,它就不再需要了。更改为each.requires recent ruby,不过:)@SergioTulentsev的确,2.0
已经不是很新了,不过:)我真的很喜欢产品。不错;)product
示例将为每一对使用相同的哈希实例,可能不是OP想要的:-@SergioTulentsev修改hash[arr.zip([{}]*arr.size)]
将使其向后兼容,不会出现问题。这可能是最好的解决方案。我刚刚在pry
中运行了它,它返回一个空哈希,而不是与arr
中的键匹配的哈希的哈希。我错过了什么?@Beartech,就像我说的,它很懒。一旦你访问了一个密钥,你会得到一个空的散列或者nil
,这取决于该密钥是否在数组中。这可能是一个很好的方法(我特别喜欢条件子句),但是OP明确指出,所需的散列应该是h={a:{},b:{},c:{}
(不是空散列)。如果在创建散列后,OP想要立即执行h.keys
?@caryswovel,并且可以通过这种方式执行h=hash.new{hash,key{hash[key]={}if arr.include?key};h、 值_at(*arr)
将立即在h
内创建这些键,但我同意它缺乏一定的吸引力。我的建议:删除最后三行。我的建议:删除最后四行。:-)(永远不要提供最佳解决方案的替代方案——这只会削弱你的答案。)你使用了吗?@caryswovel如果你将sup
和sub
结合起来,它会变得更小。事实上,您似乎可以使文本任意变小。如果感兴趣,请在链接中查看我的答案的修订历史。我刚刚做了一个编辑。标题有点不清楚,因为提到了“默认值”。如果您只是想创建一个散列,其键包含在给定数组中,其值为空散列,那么这与“默认”值无关。另一方面,如果在拥有hsh={a:{},b:{},c:{}}
之后执行hsh.delete(:a),则确实需要默认值;hsh[:a]
并期望结果是{}
而不是nil
。一个很好的观点,但有一点需要澄清。啊,是的,我明白为什么它不清楚。我之所以使用“default values”这个短语,是因为选择空哈希作为值是一种特殊情况——一般情况下包括使用空数组、零等作为值,对我来说,这些值是“default”(而不是特殊分配的)值的类型。您认为哪种措辞更好?可能是“如何将数组转换为具有指定公共值的哈希”。你不需要“最简洁的方式”;这就是SO的游戏名称。别忘了选择一个答案,假设至少有一个答案是有用的。
{:a=>{}, :b=>{}, :c=>{}}