我正在做一个编码练习(只是为了事先澄清任何问题)。我的目标是能够将哈希键偏移指定的数量。我遇到的问题是哈希键是否是一个符号。我的方法是把它变成一根绳子,然后从那里开始。这是我的代码:
class :: Hash
def transpose_key(offset)
self.each_key{|key|
t = (key.to_s.ord - "a".ord + offset)
key = (t % 26) + "a".ord.chr
}
return self
end #def
end #class
wrong_keys = { :a => "rope", :b => "knife", :x => "life-jacket", :z => "raft" }
puts wrong_keys.transpose_key(2)
我收到以下错误:
test.rb:6:in `+': String can't be coerced into Fixnum (TypeError)
我很困惑,因为我认为 (key.to_s.ord) 会给我一个字符串字母来转换为 ascii?稍后我将为编号键添加功能。最重要的是,如果可能的话,我想使用我已经开始的方法并使其发挥作用。有什么想法吗?
更新
这是我的新代码:
def transpose(string, offset)
#string = string.chars
string.each_codepoint {|c| puts (c + offset) > 122 ? (((c - 97) + offset) % 26 + 97).chr : (c + offset).chr}
end
transpose('xyz', 5)
。输出是正确的,但它将每个字符放在不同的行上。我已经尝试了各种方法来尝试加入它,但似乎不能。如果我在迭代中使用 print 而不是 puts,则输出会连接,但我没有得到我想要的新行。为什么会这样,我该如何解决?
我很困惑,因为我认为
(key.to_s.ord)
会...
这是错误的路线。
下一行是引发错误的行,您没有执行.to_s.ord
,而是在执行.ord.to_s
:
key = (t % 26) + "a".ord.chr
"a".ord.chr
没有意义,您将字符转换为序号并转换回字符,然后尝试添加整数和字符,因此出现错误。将"a".ord.chr
替换为"a".ord
如果我正确理解你的问题,我认为这给了你想要的:
class Hash
def transpose_key(offset)
map do |key, value|
t = (key.to_s.ord - "a".ord + offset) % 26
[(t + "a".ord).chr.to_sym, value]
end.to_h
end
end
wrong_keys = { :a => "rope", :b => "knife", :x => "life-jacket", :z => "raft" }
puts wrong_keys.transpose_key(2)
# {:c=>"rope", :d=>"knife", :z=>"life-jacket", :b=>"raft"}
Array#to_h (v2.0+) 是类方法 Hash::[] (v1.0+) 的替代方法,用于将双元素数组数组转换为哈希:
a = [[1,2],[3,4]]
Hash[a] #=> {1=>2, 3=>4}
a.to_h #=> {1=>2, 3=>4}
如果我们从方法中删除.to_h
,我们会发现 map
(to_h
应用于该值)返回的值为:
[[:c, "rope"], [:d, "knife"], [:z, "life-jacket"], [:b, "raft"]]
要使用 Hash#each_key,您可以执行以下操作:
class Hash
def transpose_key(offset)
each_key.with_object({}) do |key,h|
t = (key.to_s.ord - "a".ord + offset) % 26
h[(t + "a".ord).chr.to_sym] = self[key]
end
end
end
puts wrong_keys.transpose_key(2)
# {:c=>"rope", :d=>"knife", :z=>"life-jacket", :b=>"raft"}
经过思考,我更喜欢后一种方法。