Which value for a duplicate key is ignored in a Ru

2019-07-11 03:41发布

If a hash has more than one occurrences of identical keys pointing to different values, then how does Ruby determine which value is assigned to that key?

In other words,

hash = {keyone: 'value1', keytwo: 'value2', keyone: 'value3'}

results in

warning: duplicated key at line 1 ignored: :keyone

but how do I know which value is assigned to :keyone?

4条回答
聊天终结者
2楼-- · 2019-07-11 03:46

This is spelled out clearly in section 11.5.5.2 Hash constructor of the ISO Ruby Language Specification:

11.5.5.2 Hash constructor

Semantics

[...]

b) 2) For each association Ai, in the order it appears in the program text, take the following steps:

i) Evaluate the operator-expression of the association-key of Ai. Let Ki be the resulting value.

ii) Evaluate the operator-expression of the association-value. Let Vi be the resulting value.

iii) Store a pair of Ki and Vi in H by invoking the method []= on H with Ki and Vi as the arguments.

查看更多
做个烂人
3楼-- · 2019-07-11 03:53

IRB is your friend. Try the following in the command line:

irb
hash = {keyone: 'value1', keytwo: 'value2', keyone: 'value3'}
hash[:keyone]

What did you get? Should be "value3".

Best way to check these things is simply to try it out. It's one of the great things about Ruby.

查看更多
可以哭但决不认输i
4楼-- · 2019-07-11 04:00

The last one overwrites the previous values. In this case, "value3" becomes the value for :keyone. This works just as the same with merge. When you merge two hashes that have the same keys, the value in the latter hash (not the receiver but the argument) overwrites the other value.

查看更多
爷、活的狠高调
5楼-- · 2019-07-11 04:08

Line numbers on duplicate key warnings can be misleading. As the other answers here confirm, every value of a duplicated key is ignored except for the last value defined for that key.

Using the example in the question across multiple lines:

1 hash1 = {key1: 'value1',
2 key2: 'value2', 
3 key1: 'value3'}
4 puts hash1.to_s

keydup.rb:1: warning: duplicated key at line 3 ignored: :key1
{:key1=>"value3", :key2=>"value2"}

The message says "line 3 ignored" but, in fact it was the value of the key defined at line 1 that is ignored, and the value at line 3 is used, because that is the last value passed into that key.

查看更多
登录 后发表回答