ruby 生成哈希值

Ruby’s Hash object is an associative data structure used to store key-value pairs. Many languages have objects that serve a similar purpose: Python has dictionaries, JavaScript has Maps, Java has HashMaps, and so on. Ruby’s Hash object is pretty simple to use.

Ruby的Hash对象是用于存储键值对的关联数据结构。 许多语言的对象都具有类似的目的:Python具有字典,JavaScript具有Maps,Java具有HashMaps,依此类推。 Ruby的Hash对象非常易于使用。

my_hash = {}my_hash[0] = 'Hello!'puts my_hash[0]#=> Hello!

This works just fine. We can also change the value associated with a key that already exists in the hash.

这样很好。 我们还可以更改与哈希中已存在的键关联的值。

my_hash[0] << "I've been mutated!"puts my_hash[0]#=> Hello! I've been mutated!

The [] operator is just syntactic sugar for the #[] method defined in the Hash class. Here is the description from the Ruby Docs:

[]运算符只是Hash类中定义的#[]方法的语法糖。 这是Ruby Docs中的描述:

hsh[key] → value

hsh [key]→值

Retrieves the value object corresponding to the key object. If not found, returns the default value.

检索与对象相对应对象。 如果找不到,则返回默认值。

The last sentence in this description deserves a bit more explanation.

此描述中的最后一句话值得更多解释。

my_hash = {}my_hash[:exists] = 0my_hash[:exists] += 1puts my_hash[:exists]#=> 1my_hash[:does_not_exist] += 1#=> NoMethodError (undefined method `+' for nil:NilClass)

Hashes have a default value, which is the value returned when accessing keys that do not exist in the hash. In the code above, we are attempting to access the key :does_not_exist and then call the #+ method on the value associated with that key. The error message tells us that there is no #+ method defined for the value that is returned by accessing this key. This is because hashes initialized using the code hash_name = {} will have their default value set to nil.

哈希具有默认值,该默认值是访问哈希中不存在的键时返回的值。 在上面的代码中,我们尝试访问键:does_not_exist ,然后对与该键关联的值调用#+方法。 该错误消息告诉我们,没有为通过访问此键返回的值定义#+方法。 这是因为使用代码hash_name = {}初始化的哈希将其默认值设置为nil

p my_hash[:does_not_exist]#=> nil

We can set the default value ourselves by using the Hash::new method:

我们可以使用Hash::new方法Hash::new设置默认值:

my_hash = Hash.new(0)my_hash[:does_not_exist] += 1puts my_hash[:does_not_exist]#=> 1

None of this is particularly mind-blowing, but what happens if we try to run this code:

这些都不是特别令人神往的,但是如果我们尝试运行以下代码会发生什么:

my_hash = Hash.new([])my_hash[:does_not_exist] << 'Uh oh.'p my_hash#=> {}p my_hash[:does_not_exist]#=> ["Uh oh."]

Wait a minute. The p method uses the #inspect method to print a human-readable representation of the object passed in. So you may have expected to see {:does_not_exist=>["Uh oh."]}, but instead it looks like the hash is still empty. But if we retrieve the value associated with the :does_not_exist symbol (which, as its name implies, does not exist), we get the value we expected.

等一下。 p方法使用#inspect方法来打印传入的对象的人类可读表示。因此,您可能希望看到{:does_not_exist=>["Uh oh."]} ,但是看起来像是哈希仍然是空的。 但是,如果检索与:does_not_exist符号关联的值(顾名思义,该符号不存在),我们将获得预期的值。

p my_hash[:does_not_exist_either]#=> ["Uh oh."]

Alright, this is weird. It looks like the hash has key-value pairs that we didn’t even specify.

好吧,这很奇怪。 看起来散列具有我们甚至未指定的键值对。

There is actually a reasonable explanation for this, but it requires careful attention to the description of the Hash::new method in the Ruby Docs.

实际上对此有一个合理的解释,但是需要仔细注意Ruby Docs中对Hash::new方法的描述。

new → new_hash

新→new_hash

new(obj) → new_hash

new(obj)→new_hash

Returns a new, empty hash. If this hash is subsequently accessed by a key that doesn’t correspond to a hash entry, the value returned depends on the style of new used to create the hash. In the first form, the access returns nil. If obj is specified, this single object will be used for all default values.

返回一个新的空哈希。 如果此哈希随后被与哈希条目不对应的键访问,则返回的值取决于用于创建哈希new样式 在第一种形式中,访问返回nil 如果指定了obj,则此单个对象将用于所有默认值

The last sentence is key. When we initialize a hash using Hash.new([]), we are passing in an array object. This single object will be used as the default value for the hash. We can prove this by printing a few object ids.

最后一句话是关键。 当我们使用Hash.new([])初始化哈希时,我们传入一个数组对象。 该单个对象将用作哈希的默认值。 我们可以通过打印一些对象ID来证明这一点。

my_hash = Hash.new([])my_hash[0] << 1puts my_hash[0].object_id#=> 180puts my_hash[:does_not_exist].object_id#=> 180

When we use the << operator on the second line of this code, we aren’t mutating the hash at all. In fact, we are mutating the default value that the Hash#[] method returns when we attempt to access a key that doesn’t exist. Think carefully about what is happening in this code:

当我们在此代码的第二行使用<<操作符时,我们根本就不会改变哈希值。 实际上,当我们尝试访问不存在的键时,我们正在改变Hash#[]方法返回的默认值。 仔细考虑一下这段代码中发生了什么:

Line 1: We invoke the Hash::new method, passing in an empty array object as the argument. This returns a new hash object which will use the empty array object as the default value.

第1行:我们调用Hash::new方法,传入一个空数组对象作为参数。 这将返回一个新的哈希对象,它将使用空数组对象作为默认值。

Line 2: We use the [] operator on the hash, which is syntactic sugar for the Hash#[] method. We pass in the integer 0 as the argument for this method. Because there is no key with the value 0 in our hash, the method returns the default value (our single empty array object). We then use the << operator to invoke the Array#<< method to mutate that empty array object, not the hash! We pass an integer with value 1 into the #<< method, which appends that integer onto the end of our formerly empty array. The key here is that our hash is left unchanged by this code.

第2行:我们在哈希上使用[]运算符,它是Hash#[]方法的语法糖。 我们传入整数0作为此方法的参数。 由于哈希中没有键值为0键,因此该方法返回默认值(我们的单个空数组对象)。 然后,我们使用<<操作符调用Array#<<方法来变异该空数组对象,而不是哈希! 我们将一个值为1的整数传递给#<<方法,该方法将该整数附加到我们以前为空的数组的末尾。 关键是此代码不会使我们的哈希保持不变

Consider this code:

考虑以下代码:

my_array = []my_hash = Hash.new(my_array)my_hash[0] << 1p my_hash#=> {}p my_array#=> [1]p my_array.object_id#=> 200p my_hash[:does_not_exist].object_id#=> 200

This code is fundamentally the same as the previous code snippet, except this should make it clear that it is our default value that is being mutated, not the hash.

该代码与前面的代码片段基本相同,不同之处在于,这应该使我们清楚是突变的是我们的默认值,而不是哈希值。

What we’ve discovered here is not unique to arrays as hash values. This same concept applies for all mutable objects.

我们在这里发现的并不是数组作为哈希值所独有的。 同样的概念适用于所有可变对象。

my_string = ''my_hash = Hash.new(my_string)my_hash[0] << 'nope.'p my_hash#=> {}p my_string#=> "nope."

So, is there another way to make this work? Can we use a mutable object as a default value and have it work as we originally expected? To answer this question, we have to take another look at the Ruby Docs for the Hash::new method.

那么,还有另一种方法可以使这项工作吗? 我们可以使用可变对象作为默认值,并使它按我们最初的预期工作吗? 要回答这个问题,我们必须再看看Hash::new方法的Ruby Docs 。

…If a block is specified, it will be called with the hash object and the key, and should return the default value. It is the block’s responsibility to store the value in the hash if required.

…如果指定了一个块,它将被哈希对象和键调用,并应返回默认值。 如果需要,将值存储在哈希中是块的责任。

Alright, so we can pass a block into the Hash::new method. That means we can change our code to look like this:

好了,所以我们可以将一个块传递给Hash::new方法。 这意味着我们可以将代码更改为如下所示:

my_hash = Hash.new { |hash, key| hash[key] = [] }my_hash[0] << 'This works!'my_hash[1] << 'This works too!'p my_hash#=> {0=>["This works!"], 1=>["This works too!"]}p my_hash[0].object_id#=> 220p my_hash[1].object_id#=> 240

So what is happening here? On line 1, we are again invoking the Hash::new method. But this time, we are passing in a block instead of an array object. As the docs state, when we attempt to access a key that does not exist this block will be called. The hash object and the key we are trying to access will be passed as arguments into the block. Within the block, we will associate a new unique array object with the object assigned to key. The return value of the Hash#[]= operator is the value used for the assignment, so our block will also return that same value. This fulfills the obligation to return the default value from the block, as stated in the description of the Hash::new method.

那么这里发生了什么? 在第1行,我们再次调用Hash::new方法。 但是这次,我们传递的是块而不是数组对象。 正如文档所述,当我们尝试访问不存在的密钥时,将调用此块。 我们尝试访问的哈希对象和密钥将作为参数传递到块中。 在该块内,我们将一个新的唯一数组对象与分配给key的对象相关联。 Hash#[]=运算符的返回值是用于赋值的值,因此我们的块也将返回相同的值。 如Hash::new方法的描述中所述,这履行了从块中返回默认值的义务。

There is an arguably simpler solution. We don’t have to pass a block into the Hash::new method if we just don’t try to mutate the default value.

有一种可能更简单的解决方案。 如果我们只是不尝试更改默认值,则不必将块传递给Hash::new方法。

my_hash = Hash.new([])my_hash[:does_not_exist] += ['Uh oh.']p my_hash#=> {:does_not_exist=>["Uh oh."]

Pay close attention to the operators used on line 2. Instead of mutating the array with the << operator, we use the += operator to construct a new string and then assign it to the key :does_not_exist. Our default value is left alone and our hash is correctly mutated.

请密切注意第2行上使用的运算符。我们没有使用<<操作符来对数组进行变异,而是使用+=运算符构造了一个字符串,然后将其分配给键:does_not_exist 。 我们的默认值不理会,我们的哈希值正确变异。

I hope that you found this helpful, or at least somewhat interesting. I ran into this problem and was pretty confused about what was going on. Figuring out why the code wasn’t doing what I expected was a great learning opportunity and reasoning through it was a great opportunity to describe, in detail, exactly what the code I had written was doing. I would like to credit Andrew Marshall for a very helpful explanation on this topic posted on Stack Overflow a few years ago.

我希望您觉得这很有帮助,或者至少有点有趣。 我遇到了这个问题,对发生的事情感到非常困惑。 弄清楚为什么代码没有按照我的预期去做是一个很好的学习机会,而通过它进行推理是一个很好的机会来详细描述我编写的代码在做什么。 我要感谢安德鲁·马歇尔( Andrew Marshall)几年前在Stack Overflow上发布的有关此主题的非常有用的解释。

翻译自: https://medium.com/@lawnfurniture_20661/ruby-hashes-and-mutable-default-values-df8841eba25b

ruby 生成哈希值


http://www.taodudu.cc/news/show-3783606.html

相关文章:

  • 算法训练Day6 | LeetCode:242. 有效的字母异位词(数组作哈希表);349. 两个数组的交集(Set作哈希表);202.快乐数 (Set作哈希表);1. 两数之和(Map作哈希表)
  • 【代码随想录 | day06】(JavaScript) 哈希表理论基础以及相关算法题
  • hash table html,javascript 哈希表(hashtable)的简单实现
  • 颗分仪025-57714709(南京粒度仪科技)
  • 2020年全球铀矿产量为4.77万吨,其中40.8%产自哈萨克斯坦[图]
  • 对钙铀云母放射强度的测量
  • 自制用于放置钙铀云母的铅盒
  • 二进制位,字节,字,字长的概念与区分
  • 字节地址和位地址有什么区别
  • c语言二进制数怎么表示_C语言的二进制数、位和字节
  • 10003---位(bit)、字节(Byte)、MB(兆位)之间的换算关系
  • 计算机 字节、位等之间的换算
  • 逻辑回归原理及解析
  • 二分类问题:逻辑回归原理
  • 逻辑回归原理简述及代码实现
  • 逻辑回归原理与实现
  • 逻辑回归原理及其推导
  • 逻辑回归原理理解及公式推导
  • 【TensorFlow】逻辑回归原理与实现(超详细)
  • 逻辑回归原理及matlab实现
  • 【机器学习】逻辑回归原理介绍
  • 分类问题常用算法——逻辑回归原理
  • 【机器学习】 逻辑回归原理及代码
  • 逻辑回归原理与代码
  • 逻辑回归原理详细推导
  • 逻辑回归(Logistic Regression)原理及其应用
  • FTP 主动模式、被动模式
  • LINUX---FTP两种工作模式:主动模式和被动模式
  • ftp协议主动模式与被动模式
  • FTP工作原理以及主动模式和被动模式

ruby 生成哈希值_Ruby哈希值和可变的默认值相关推荐

  1. java默认值_Java中八种基本数据类型的默认值

    通过一段代码来测试一下 8种基本数据类型的默认值 package dierge; public class Ceshi { int a; double b; boolean c; char d; fl ...

  2. hibernate映射数据库表如何在不插入值的情况下使表中字段默认值生效

    问题描述:    hibernate技术中对应数据库中每一个表,都会有一个映射文件与之对应,此文件描述数据库表中每一个字段的类型.长度.是否可空等属性.在进行表中记录的插入(更新)操作时,hibern ...

  3. mysql jpa默认值_Spring JPA-枚举中枚举字段的默认值

    我们有一个带有枚举字段-的实体emailCommunicationStatus,我们想使用JPA注释-为它设置默认值'UNKNOWN'. 但是,当我们将实体保存到数据库时,此字段的值为null和.对于 ...

  4. mysql增加字段设默认值_mysql原表增加字段且设置默认值及修改字段默认值

    -- 增加字段及注释 alter table sr_zjff_main add zjbzjxbj int(1) DEFAULT '0' COMMENT ''; alter table sr_main_ ...

  5. mysql设置当前时间为默认值_MySQL的datetime设置当前时间为默认值

    由于MySQL目前字段的默认值不支持函数,所以以 create_time datetime default now() 的形式设置默认值是不可能的. 代替的方案是使用TIMESTAMP类型代替DATE ...

  6. php textarea 默认值,html中的textarea属性大全(设置默认值 高度自适应 获取内容 限制输入字数 placeholder)...

    1.textarea设置默认值 HTML: 此段代码设置一个textarea文本框 并且设置为隐藏 2.textarea高度自适应 今天需要些一个回复评论的页面,设计师给的初始界面就是一个只有一行的框 ...

  7. python input 默认值_在python中为dictionary创建默认值

    让我们有一个方法来缓存它计算的结果. "If"方法:def calculate1(input_values): if input_values not in calculate1. ...

  8. java的下拉框的设置默认值,html下拉选项属性 html下拉框怎么设置默认值?

    html下拉框怎么设置默认值 设置selected属性就可以,具体的用法,首先打开hbuilder软件,新建一个html文档,里面写入一个select下拉框: 然后给select中一个option设置 ...

  9. Java之数组的定义格式,【默认值规则】,Java内存划分5大区,面向对象类的基本定义和对象的使用,private和this关键字,类的构造方法,标准类的组成部分。

    目录 1.数组 动态初始化数组的格式: 默认值规则 静态初始化数组的格式: 静态方式的省略格式 注意: 2.java的内存划分 3.数组内存图 4.数组常见的问题 5.面向对象 (1)类和对象 (2) ...

最新文章

  1. PHP 打印调用堆栈信息
  2. python自学平台-Python学习交流平台与教程推荐
  3. 1.3 图像边缘检测edge函数的用法
  4. java 调用win32 api 学习总结
  5. 硬核! 逛了4年Github ,一口气把我收藏的 Java 开源项目分享给你
  6. 硬件芯片选型原理图设计
  7. okex java sdk_OKEX官网新手使用教程
  8. 在RH6.5上安装sublime3 build3103步骤
  9. PHP删除数组中的空值
  10. MATLAB_平面几何_判断两平面矩形是否干涉
  11. python个人所得税怎么写分录_个人所得税的会计分录!
  12. mysql怎么保证最少一条消息_MySQL 的一条语句是怎么执行的
  13. matlab2c使用c++实现matlab函数系列教程- polyint函数
  14. 实验7 OpenGL光照
  15. 那些不需要你知道的Chrome DevTool - 使用技巧篇
  16. 彻底了解Cookie
  17. c语言 宏常量 pi,宏和常量
  18. payscale 美国计算机专业,2016PayScale美国大学排名:计算机专业
  19. 软件系统等保方案,市政项目,投标项目必须
  20. Xilinx IOB输出寄存器约束笔记

热门文章

  1. SCIP求解整数规划实例
  2. 开发一款图片压缩工具:使用 pngquant 实现图片压缩
  3. GWAS分析中使用PCA校正群体分层
  4. H.264视频编码标准在网络视频监控系统中的应用
  5. vs2010 瘦身--ipch文件夹和sdf文件配置
  6. Linux字体-Linux中文字体(mkfontscale mkfontdir fc-cache -fv命令)
  7. 【个人笔记】Python-Pandas写入Excel多个sheets
  8. soul2.3 初体验
  9. Bright Data Proxy和ClonBrowser浏览器,双重助力打造高效数据采集系统
  10. less语法,简单明了