[英]Generate a hash of all letters and digits
Using ruby, how do I make a hash of each letter in the alphabet (keys) and 1-26 (values)?使用 ruby,如何对字母表(键)和 1-26(值)中的每个字母进行哈希处理?
I need to create a hash with "a" to "z" in keys and 1 to 26 in values but I do not want to write myself alphabet = {'a'=>1,'b'=>2,....'y'=>25,'z'=>26}
我需要创建一个散列,键为“a”到“z”,值为 1 到 26,但我不想自己写alphabet = {'a'=>1,'b'=>2,....'y'=>25,'z'=>26}
I need this in my code to print alphabet[i] if alphabet.key?(i)
我的代码中需要这个来打印alphabet[i] if alphabet.key?(i)
('a'..'z').each.with_index(1).to_h
#=> {"a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5, "f"=>6, "g"=>7, "h"=>8, "i"=>9, "j"=>10,
# "k"=>11, "l"=>12, "m"=>13, "n"=>14, "o"=>15, "p"=>16, "q"=>17, "r"=>18, "s"=>19,
# "t"=>20, "u"=>21, "v"=>22, "w"=>23, "x"=>24, "y"=>25, "z"=>26}
Steps:脚步:
('a'..'z')
- create a Range
of alphabetic letters "a" through "z" inclusive ('a'..'z')
- 创建一个从“a”到“z”的字母Range
each
- returns an Enumerator
each
- 返回一个Enumerator
with_index(1)
- returns an Enumerator
of each element of the initial Range combined with its index (starting at 1) eg [["a",1],["b",2],...]
with_index(1)
- 返回初始范围的每个元素及其索引(从 1 开始)的Enumerator
器,例如[["a",1],["b",2],...]
to_h
- convert the Enumerator
to a Hash
to_h
- 将Enumerator
器转换为Hash
Update :更新:
A bit more esoteric but this will also work有点深奥,但这也可以
enum = Enumerator.produce('a') {|e| e == 'z' ? raise(StopIteration) : e.succ }.tap do |e|
e.define_singleton_method(:[]) {|elem| find_index(elem)&.+(1) }
e.define_singleton_method(:to_h) { with_index(1).to_h }
end
enum['w']
#=> 23
enum['W']
#=> nil
enum.to_h
#=> {"a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5, "f"=>6, "g"=>7, "h"=>8, "i"=>9, "j"=>10,
# "k"=>11, "l"=>12, "m"=>13, "n"=>14, "o"=>15, "p"=>16, "q"=>17, "r"=>18, "s"=>19,
# "t"=>20, "u"=>21, "v"=>22, "w"=>23, "x"=>24, "y"=>25, "z"=>26}
With two ranges, zip
and to_h
有两个范围, zip
和to_h
('a'..'z').zip(1..26).to_h
Hash[('a'..'z').zip(1.upto(26))]
Depending on requirements you may be able to save memory by using an empty hash with a default proc.根据要求,您可以通过使用带有默认过程的空散列来节省内存。
h = Hash.new do |_h,k|
k.is_a?(String) && k.match?(/\A[a-z]\z/) ? (k.ord - 96) : nil
end
#=> {}
h['a'] #=> 1
h['z'] #=> 26
h['R'] #=> nil
h['cat'] #=> nil
h[2] #=> nil
h[{a:1}] #=> nil
See Hash::new and String#match?请参阅Hash::new和String#match? . .
The regular expression reads, "match the beginning of the string ( \A
) followed by one lowercase letter ( [az]
) followed by the end of the string ( \z
). [az]
denotes a character class .正则表达式为,“匹配字符串的开头 ( \A
),后跟一个小写字母 ( [az]
),然后是字符串的结尾 ( \z
)。 [az]
表示一个字符类。
If all lowercase letters must comprise the hash's keys one may write the following.如果所有小写字母都必须包含散列的键,则可以编写以下内容。
('a'..'z').to_h { |c| [c, c.ord - 96] }
#=> {"a"=>1, "b"=>2,..., "y"=>25, "z"=>26}
See Enumerable#to_h .请参阅Enumerable#to_h 。
There have been better answers given already, but here's an entirely different option using a times
loop to simply increment the keys and values of a starter hash using next
:已经给出了更好的答案,但这里有一个完全不同的选项,它使用times
循环来简单地使用next
增加起始哈希的键和值:
h = {"a" => 1}
25.times {h[h.keys.last.next] = h.values.last.next}
h
#=> {"a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5, "f"=>6, "g"=>7, "h"=>8, "i"=>9, "j"=>10, "k"=>11, "l"=>12, "m"=>13, "n"=>14, "o"=>15, "p"=>16, "q"=>17, "r"=>18, "s"=>19, "t"=>20, "u"=>21, "v"=>22, "w"=>23, "x"=>24, "y"=>25, "z"=>26}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.