为了这个问题,我们假设我们在Ruby中没有hash
类。
是否可以在Ruby中不使用hash
创建hash class
?或者,如果我们没有哈希概念,我们可能会将其称为associative array
。
答案 0 :(得分:2)
虽然可以使用数组来模拟哈希的行为,但性能会受到影响:
require 'fruity'
CHARS = ('a' .. 'z').to_a
ARY = CHARS.zip(CHARS)
HASH = ARY.to_h
compare do
_assoc_a { ARY.assoc('a') }
_hash_a { HASH['a'] }
_hash_m { HASH['m'] }
_assoc_m { ARY.assoc('m') }
_assoc_z { ARY.assoc('z') }
_hash_z { HASH['z'] }
end
# >> Running each test 32768 times. Test will take about 3 seconds.
# >> _hash_m is similar to _hash_z (results differ: m vs z)
# >> _hash_z is similar to _hash_a (results differ: z vs a)
# >> _hash_a is faster than _assoc_a by 2x ± 1.0 (results differ: a vs ["a", "a"])
# >> _assoc_a is faster than _assoc_m by 5x ± 1.0 (results differ: ["a", "a"] vs ["m", "m"])
# >> _assoc_m is faster than _assoc_z by 2x ± 0.1 (results differ: ["m", "m"] vs ["z", "z"])
执行反向查找,从第二个元素到第一个元素,或从值到键:
compare do
_rassoc_a { ARY.rassoc('a') }
_hash_rassoc_a { HASH.rassoc('a') }
_rassoc_m { ARY.rassoc('m') }
_hash_rassoc_m { HASH.rassoc('m') }
_rassoc_z { ARY.rassoc('z') }
_hash_rassoc_z { HASH.rassoc('z') }
end
# >> Running each test 32768 times. Test will take about 4 seconds.
# >> _rassoc_a is faster than _hash_rassoc_a by 2x ± 1.0
# >> _hash_rassoc_a is faster than _rassoc_m by 3x ± 1.0 (results differ: ["a", "a"] vs ["m", "m"])
# >> _rassoc_m is similar to _hash_rassoc_m
# >> _hash_rassoc_m is similar to _rassoc_z (results differ: ["m", "m"] vs ["z", "z"])
# >> _rassoc_z is similar to _hash_rassoc_z
对我来说,对密钥的散列的反向查找会更慢,因为哈希不是针对这些事情进行优化的。如果我需要这样做,我尝试创建一个单独的Hash,反转键和值,然后用它来进行反向查找:
hash = {'a' => 1, 'b' => 2}
reversed_hash = hash.invert # => {1=>"a", 2=>"b"}
如果值是数组或值不是唯一的,则会中断,有时生成的密钥使用起来非常方便。
答案 1 :(得分:2)
是否可以在Ruby中不使用
hash
创建hash class
?或者可能如果我们没有哈希概念,我们可能会将其称为associative array
。
当然。为什么不呢?哈希表的概念与任何特定语言无关。
此外,Ruby是一种图灵完备语言,这意味着您可以使用任何其他语言计算Ruby中的所有内容。
Rubinius's Hash
class是用纯Ruby编写的,显然它不能使用Hash
类,所以显然可以在纯Ruby中编写Hash
。为什么不呢? YARV的Hash
类是用C语言编写的,JRuby的Hash
类是用Java编写的,IronRuby是用C语写的,Topaz是用RPython编写的,如果你想在Ruby中编写一个,你只需“写”与所有人一样,除了在Ruby而不是C,Java,C♯或RPython中。
(公平地说,Rubinius的Hash
实现使用Tuple
,这是partially implemented in C++,但同样,你只需要在Ruby中重新编写代码,等等,你有Ruby中的Hash
类。)
答案 2 :(得分:1)
当然可以。
如果您不想重新创建自己的哈希类,可以使用Array类的assoc
和rassoc
方法。请参阅" Associative arrays in Ruby...what?"。
示例:
picks = [
["AAPL", "buy"],
["GOOG", "sell"],
["MSFT", "sell"]
]
print picks.assoc("AAPL")
puts #new line
print picks.rassoc("sell") #gets the first row that contains
输出:
["AAPL", "buy"]
["GOOG", "sell"]