简体   繁体   English

生成所有字母和数字的散列

[英]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有两个范围, zipto_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::newString#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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM