简体   繁体   English

什么是Ruby相当于Python的defaultdict?

[英]What's the Ruby equivalent of Python's defaultdict?

In Python, I can make a hash where each element has a default value when it's first referenced (also know as "autovivification"). 在Python中,我可以创建一个散列,其中每个元素在首次引用时都具有默认值(也称为“autovivification”)。 Here's an example: 这是一个例子:

from collections import defaultdict
d = defaultdict(int)
d["new_key"] += 1
print d

Printing the dict shows the value for "new_key" is 1. 打印dict显示“new_key”的值为1。

What's the equivalent in Ruby? Ruby中的等价物是什么? This code throws an error: 此代码抛出错误:

d = {}
d[:new_key] += 1
puts d

test.rb:3:in `<main>': undefined method `+' for nil:NilClass (NoMethodError)

You can assign a default value using default= : 您可以使用default=指定默认值:

d.default = 0

Note that this won't really autovivify though, it just makes d[:new_key] return a zero without actually adding a :new_key key. 请注意,这不会真正自动生成,它只是使d[:new_key]返回零而不实际添加:new_key键。 default= can also cause problems if you intend to modify the default value; 如果您打算修改默认值, default=也会导致问题; that means that d.default = [ ] is almost always a mistake as the array will not be copied when the default is accessed. 这意味着d.default = [ ]几乎总是一个错误,因为访问默认值时不会复制数组。

A better choice is usually default_proc= : 更好的选择通常是default_proc=

d.default_proc = proc { |h, k| h[k] = 0 }

This allows you to have distinct default values and it allows you to add the new key (or not depending on how the proc is structured). 这允许您具有不同的默认值,并允许您添加新键(或不取决于proc的结构)。

You can also set these when creating the Hash: 您还可以在创建哈希时设置这些:

d = Hash.new(0)
d = Hash.new { |h, k| h[k] = 0 }

You can use the first argument of the Hash.new method for that: 您可以使用Hash.new方法的第一个参数:

d = Hash.new 0
d[:new_key] += 1
d[:new_key] #=> 1
d[:foo]     #=> 0

Be careful - you might accidentally change the default value: 小心 - 您可能会意外更改默认值:

h = Hash.new("Go Fish")
h[:unknown_key]         #=> "Go Fish"
h[:unknown_key].upcase! #=> "GO FISH"
h[:next_key]            #=> "GO FISH"

As "mu is too short" pointed out in his answer, you should better use a proc, as in: 由于在他的回答中指出“mu太短”,你应该更好地使用proc,如:

h = Hash.new { |h, k| h[k] = 0 }

The standard new method for Hash accepts a block. Hash的标准new方法接受块。 This block is called in the event of trying to access a key in the Hash which does not exist. 如果尝试访问Hash中不存在的密钥,则调用此块。 The block is passed the Hash itself and the key that was requested (the two parameters) and should return the value that should be returned for the requested key. 该块传递Hash本身和请求的密钥(两个参数),并应返回应为请求的密钥返回的值。

This can be used to create an autovivified hash, among other things: 这可用于创建自动生成的哈希,以及其他内容:

h = Hash.new{ |h,k| h[k] = 'default value'}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM