Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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_Hash - Fatal编程技术网

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=>{}}