我的Rubocop罪行告诉我,我需要“使用条件的返回值进行变量分配和比较”
当我尝试修复它时,这又给了我我“方法线太长”的冒犯。
我试图重构为另一种方法,但是我的代码坏了。
如何缩短或重构此代码?
HSH = { 'a' => 'z', 'b' => 'y', 'c' => 'x', 'd' => 'w', 'e' => 'v', \
'f' => 'u', 'g' => 't', 'h' => 's', \
'i' => 'r', 'j' => 'q', 'k' => 'p', 'l' => 'o', 'm' => 'n' }.freeze
def encoder(str)
encoded_string = ''
str.chars.each do |char|
encoded_string = if HSH.key?(char) then encoded_string += HSH[char]
elsif HSH.invert.key?(char) then encoded_string += HSH.invert[char]
else encoded_string += char
end
end
encoded_string
end
运行测试套件时,一切正常。
但是鲁比科普犯罪给了我方法线太长。
答案 0 :(得分:4)
无哈希:
// Setting the CartoDB tile (you can use any tile you want)
var tile = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
bounds: [[-90,-180],[90,180]],
attribution:'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> © <a href="http://cartodb.com/attributions">CartoDB</a>',
subdomains:'abcd'
});
// Setting the map parameters
var map = L.map('map', {
maxBounds: [[-90,-180],[90,180]],,
minZoom: 0,
maxZoom: 18,
fullscreenControl: true
})
.addLayer(tile)
.setView([0, 0], 12);
// Here the events for zooming and dragging
map.on('zoomend', function() {
// stuff here when user zooms the map...
});
map.on('dragend', function() {
// stuff here when user drags the map...
});
答案 1 :(得分:2)
HSH = {
'a' => 'z', 'b' => 'y', 'c' => 'x',
'd' => 'w', 'e' => 'v', 'f' => 'u',
'g' => 't', 'h' => 's', 'i' => 'r',
'j' => 'q', 'k' => 'p', 'l' => 'o',
'm' => 'n'
}.freeze
def encoder(str)
str.chars.map { |char| HSH[char] || HSH.invert[char] || char }.join
end
答案 2 :(得分:1)
注意!不要使用此答案! @steenslag here提供了正确的解决方法。
使用哈希与所有明确映射的字母 和默认proc:
HSH =
(?a..?z).zip((?a..?z).to_a.reverse).to_h.
tap { |h| h.default_proc = ->(_, k) { k }}.
freeze
def encoder(str)
str.chars.map(&HSH.method(:[])).join
end
答案 3 :(得分:1)
我们中的一些人建议了更好的方法来实现您的encoder
方法。但是我们所有人(包括我自己)都没有真正回答您的问题,或者在您的代码中看到了中心问题:
我的Rubocop罪行告诉我,我需要“使用条件的返回值进行变量分配和比较”
当我尝试修复它时,这又给了我我“方法线太长”的冒犯。
encoded_string = if HSH.key?(char) then encoded_string += HSH[char]
elsif HSH.invert.key?(char) then encoded_string += HSH.invert[char]
else encoded_string += char
end
您遵循了Rubocop的建议...您为一个值分配了条件结果...但我认为您错过了分数。我什至不确定那是它所指的条件结果。我假设您添加了encoded_string = ...
分配。
这是一个无用的分配,因为您已经在if
块内将字符附加到了encode_string上。您不必再次分配它。
回到我猜测的是您的版本1代码,这是遵循Rubocop的建议的一种更有效的方法。不要在每个条件内都进行赋值...只做一个赋值,条件是:
encoded_string += if HSH.key?(char) then HSH[char]
elsif HSH.invert.key?(char) then HSH.invert[char]
else char
end
最后,所需的代码更少,并且与您的原始编码风格和方法相匹配。它甚至可能使Rubocop高兴。可爱代码的下一步是消除过多的key?
测试:
encoded_string += if HSH[char] then HSH[char]
elsif HSH.invert[char] then HSH.invert[char]
else char
end
从那里开始,用if/elsif
消除||
块是一小步。并且在进行处理时,我们将+=
更改为<<
以避免“产生大量中间不必要的String实例”。 (感谢您的建议,@ Aleksei Matiushkin)
encoded_string << HSH[char] || HSH.invert[char] || char
对于您解决此问题的方法,这就是生产代码应争取的最低程度的简洁性和可读性。任何人都可以理解它,而无需真正地努力或达到Stack Overflow。
答案 4 :(得分:0)
我会继续将您的哈希扩展到所有26个字母,这样您就可以避免反向查找。通过删除一种情况可以简化Rubocop,从而简化了代码。但是更重要的是,您将使用哈希索引来提高效率和性能。反向哈希查找非常昂贵,因为它必须读取(最多)每个值。
考虑编码为“ 1 + 2”。它将执行三个快速索引扫描,然后进行三个全数组扫描,只返回原始字符串。
使用完全填充的哈希,只需进行三个快速扫描即可。
以下是您的原始代码,其中进行了最小的更改以实现您的目标:(执行此操作的方法更短(提示:tr
或map
),但是较短的代码不那么容易和舒适给使用代码的程序员。)
translation = {
'a' => 'z', 'b' => 'y', 'c' => 'x', 'd' => 'w', 'e' => 'v', 'f' => 'u', 'g' => 't',
'h' => 's', 'i' => 'r', 'j' => 'q', 'k' => 'p', 'l' => 'o', 'm' => 'n', 'n' => 'm',
'o' => 'l', 'p' => 'k', 'q' => 'j', 'r' => 'i', 's' => 'h', 't' => 'g', 'u' => 'f',
'v' => 'e', 'w' => 'd', 'x' => 'c', 'y' => 'b', 'z' => 'a'
}.freeze
def encoder(str)
encoded_string = ''
str.chars.each do |char|
encoded_string << translation[char] || char
end
encoded_string
end
您甚至可以考虑将哈希扩展为大写和小写字母,甚至所有256个char值,具体取决于要解决的问题。但是,让我们同意忽略Unicode字符!
回到Rubocop ...对任何“太长/太复杂”警告的最简单,确定有效的解决方案是将代码提取到新方法中。编写def charswap
并将其用作循环的主体。这将使编写测试变得更容易引导。但是,通过将翻译数组扩展到所有26个字母,代码变得如此简单,以至于真正不需要重构。
答案 5 :(得分:0)
与@Steenslag的答案一样,无需将字符串转换为数组,映射数组的每个元素并将结果重新组合为字符串。
def encode_decode(str)
str.gsub(/./) { |c| ('a'..'z').cover?(c.ord) ? (219-c.ord).chr : c }
end
plain_text = "The launch code is 'Bal3De8Rd0asH'."
#=> "Tsv ozfmxs xlwv rh 'Bzo3Dv8Rw0zhH'."
encode_decode(coded_text)
#=> "The launch code is 'Bal3De8Rd0asH'."