ESS多版本 【TA】【ESS】09 哈希

TAAAAAAA

天王
管理成员
2024/06/16
200
3
27
1,210
9: Hashes 哈希

Introducing yet another data type: Hash. Hashes are very much like arrays in that it’s a list of objects with a specific location in the array/hash. The key difference (pun intended) is that objects inside arrays are always at a specific index which is a whole number between 0 and, well, infinity, whereas the “indexes” of objects inside a hash can be pretty much any object: a symbol, a string, a number, an array, another hash, or even a class.
Hashes are denoted by typing a bunch of key => value structures, separated by a comma, within two curly brackets. Here, key stands for an object of some kind, and value stands for an object of some kind. These don’t have to be the same.

现在我们来学习另一种数据类型:哈希。
哈希其实是Hash的音译,哈希简单的说的话其实就是更加“高级”的数组。
所以,数组有的一些特点,哈希全都有。
哈希和数组的不同点在于,数组通过元素的序号和值进行关联;
而哈希几乎可以使用“任何东西”和值进行关联,用来关联的这个“东西”,我们称为key,也就是键。
也就是说,哈希其实是由一对一对的key-value(键-值对)对构成的。
我们来看下面的例子:

Ruby:
hash = {
  "start" => "hello world!"
}
print hash #=> {"start"=>"hello world"}
print hash["start"] #=> "hello world"
# 可以看到,我们使用{}(大括号)来定义一个哈希,接着在大括号内部
# 填充键-值对,键和值的中间使用=>(一个等于号+一个大于号)进行连接。
# 同时,对于访问数据来说,格式和数组访问数据是一样的,都是通过xxx[]这
# 样的一个格式来访问,只不过数组使用的是序号,而哈希使用的是键。
# 我们通过hash["start"]来访问hash这个哈希中“start”(开始)这个键的值。

Like most other things in Ruby, spaces and newlines are almost always disregarded. It doesn’t matter how many or how little whitespace you have.

在Ruby中,空格和是否新起一行在不产生歧义的情况下对代码是没有影响的,虽然我可能应该在更早的时候就说到这一点。

In this example we see a hash with one key-value pair. The key is “start”, and the value that belongs to that key (in arrays, index) is “hello world!”.
Those keys aren’t limited to just strings (the logical choice, because they’re more descriptive than, say, 482 as a key), but you can also use other data types:

在上面的例子中,hash这个哈希中有一个键-值对,其中键是“start”,是一个字符串,而值是“hello world!”,同样也是一个字符串。
但是,键-值对的数据类型是可以是任意的,并不要求键和值的数据类型要一样。
我们来看下面的这个例子:

Ruby:
hash = {
  "one" => 1,
  2 => "two",
  :three => ["three",3]
}

print hash #=> {"one"=>1,2=>"two",:three=>["three",3]}
print hash["one"] #=> 1
print hash[2] #=> "two"
print hash[:three] #=> ["three",3]
print hash[:three][1] #=> 3
# 可以看到,当我们想要录入多个键-值对时,我们使用“,”(逗号)进行分隔。

Now that we know this, we could technically also make a fake “array” with hashes as long as we use numbers for the keys.

如果我们使用数字作为哈希的键的话,我们就可以用哈希来模拟一个数组了,
请看下面的例子:

Ruby:
hash = {
  0 => "zero",
  1 => "one",
  2 => "two"
}
print hash[0] #=> "zero"
print hash[1] #=> "one"
print hash[2] #=> "two"
array = [
  "one",
  "two",
  "three"
]
print array[0] #=> "zero"
print array[1] #=> "one"
print array[2] #=> "two"

From this point it’s basically like a regular ol’ array. We can use the keys to access the objects in the hash and change their values:

跟数组一样,在获取到键的值之后,我们可以给这个键重新赋值,请看下面的例子:

Ruby:
hash = {
  "three" => 3,
}

print hash["three"] #=> 3
hash["three"] = 9278343
print hash["three"] #=> 9278343

...Or we can add to it (if a key doesn’t exist in a hash, it returns nil):

而如果一个键不存在的话,就会返回nil。
我们也可以直接用xxx[yyy] = zzz这样的格式来给哈希录入更多的键-值对。
当我们这样做时,如果yyy本身在哈希里有这个键,那么就会对键重新赋值;如果哈希里没有这个键,那么就会录入这个键,并且给这个键赋值zzz。
我们来看下面的例子:

Ruby:
hash = {}
# 这是一个空哈希。

print hash["a key"] #=> nil
hash["a key"] = "a value"
# 录入了一个新的键-值对。
print hash["a key"] #=> "a value"
 
最后编辑:

TAAAAAAA

天王
管理成员
2024/06/16
200
3
27
1,210
Iterating through hashes 迭代哈希

Unlike arrays, hashes don’t have neatly organised indexes you can just iterate over. Instead, you have to loop through the keys of the hash and use those instead.

我们来看下面的这个例子:

Ruby:
hash = {
  "james" => 10,
  "carl" => 13,
  "trevor" => 21
}
print hash.keys #=> ["james", "carl", "trevor"]
# 我们对hash调用了keys(所有的键)之后,就会返回一个包含哈希所有键的数组。
# 不过这里需要注意,你看到的哈希中的键-值对的排列顺序,和实际上返回的并不
# 一定相同,因为哈希内部数据的存储是无序的。

So as you can see, Hash#keys nicely organizes the keys present in a hash. Important to note though is that the order of Hash#keys is not constant. As you add/remove/change the hash, this order may change, meaning that you can’t rely on “the first array element is “james”” and the like. It might return ["trevor", "james", "carl"] later on in your code, for instance.

However, you can still iterate through this array as long as you make use of the keys themselves.

我们可以对哈希的所有键进行迭代,请看下面的例子:

Ruby:
hash = {
  "a" => 1,
  "b" => 2,
  "c" => 3
}
for key in hash.keys
  print key
end

# hash.keys.each do |key|
#   print key
# end
# 以上是用each的写法,但是,实际上你其实并不需要这样做。
#
# hash.each do |key, value| # 方法1
#   print key
# end
#
# hash.each_key do |key| # 方法2
#   print key
# end
#
# 方法1和方法2都可以对哈希的所有键进行迭代,也就是说你其实并不需要先
# 得到一个哈希的所有键的数组,接着再对数组进行迭代,
# 而是说你其实可以直接迭代哈希。

This will print “a”, “b”, and “c” in an unknown order. You can then use hash[key] to retrieve the value of whichever key you’re currently iterating over. Another possibility is to store the keys somewhere before iterating, and then use a for-loop with a range.

Ruby:
hash = {
  "a" => 1,
  "b" => 2,
  "c" => 3
}

keys = hash.keys
for i in 0...keys.size
  print keys[i] #=> "a", "b", or "c"
  print hash[keys[i]] #=> 1, 2, or 3
end
# 这里直接略过,你自己看吧,但我还是要说,你可以这样做,但是没必要。
# 你可以直接使用我上面给出的方法1来实现同样的效果。
 

TAAAAAAA

天王
管理成员
2024/06/16
200
3
27
1,210
A bunch of useful methods for hashes 哈希的一些方法

For all code in the list below, assume the following applies:

下面我们来看一些哈希的方法,针对hash这个哈希,来看一些例子:

Ruby:
hash = {
  "one" => 1,
  "two" => 2,
  "three" => 3
}

Checking keys 检查键

Ruby:
rint hash.has_key?("three") #=> true
print hash.has_key?("four") #=> false
# 检查是否有xxx键。

print hash.key(2) #=> "two"
print hash.key(3) #=> "three"
print hash.key(4) #=> nil
# 检查是否有值为xxx的键。

Deletion 删除键值对

Ruby:
print hash["one"] #=> 1
hash.delete("one") # Give it the key you want to delete
# 删除键是“one”的键-值对。
print hash["one"] #=> nil

Checking values 检查值

Ruby:
print hash.has_value?(3) #=> true
print hash.has_value?(4) #=> false
# 检查是否有xxx值。

hash["something"] = 4
print hash.has_value?(4) #=> true
print hash.values #=> [1, 2, 3, 4]

The reason there’s no Hash#value (despite there being a Hash#key), is because you can easily fetch a value based on key with hash[key] already. This isn’t possible with fetching a key based on a value, which is why Hash#key exists.

本章完。
 

在线成员

论坛统计

主题
474
消息
2,137
成员
2,909
最新成员
小灵喵~