Jef*_*ong 2 ruby syntax conditional
似乎RubyMine IDE在看到负面条件语句时发出警告.我想知道为什么使用否定条件语句是坏的?它纯粹是因为可读性吗?
例如,在此代码中:
class Complement
def self.of_dna dna_strand
dna_array = dna_strand.chars
dna_complement = ['']
dna_structure = ['C', 'G', 'T', 'A']
dna_array.each do |strand|
unless dna_structure.include? strand
return ''
end
case strand
when "C"
dna_complement << "G"
when "G"
dna_complement << "C"
when "T"
dna_complement << "A"
when "A"
dna_complement << "U"
end
end
dna_complement.join('')
end
end
Run Code Online (Sandbox Code Playgroud)
我想知道什么是之间的不同unless dna_structure.include? strand而if !(dna_strucutre.include?)在这种情况下?
由于Ruby不仅仅是if,但是unless,只要结果代码清晰,就会鼓励您使用它.那你应该转换这样的东西:
if (!string.empty?)
# ...
end
Run Code Online (Sandbox Code Playgroud)
进入这样的事情:
unless (string.empty?)
# ...
end
Run Code Online (Sandbox Code Playgroud)
这有例外,就像你有这个:
if (!string.empty?)
# ... when not empty
else
# ... when empty (when not not empty)
end
Run Code Online (Sandbox Code Playgroud)
天真的方法是将其转换为unless但会产生三重否定.你已经在这里处理了一个double,else只有当字符串不是空的,或者可以说不包含任何东西时才会出现该子句.
改为:
if (string.empty?)
# ... when empty
else
# ... when not empty
end
Run Code Online (Sandbox Code Playgroud)
你在这里采用的方法存在许多问题,但最严重的是你每次调用方法时都会在方法中声明一个常量数组.因为从来没有改变使它成为班级顶层的常数.至少:
class Complement
DNA_STRUCTURE = %w[ C G A T ]
end
Run Code Online (Sandbox Code Playgroud)
更好的方法是使用映射表来表示配对:
COMPLEMENT = {
'C' => 'G',
'G' => 'C',
'T' => 'A',
'A' => 'U'
}.freeze
Run Code Online (Sandbox Code Playgroud)
现在看看你试图"反转"给定tr字符串的特定问题,你真正想要的工具就是字符串本身,这是一种针对像cyphers这样的事物进行优化的方法,其中字符之间有1:1的映射关系.
你的整个功能都崩溃了:
def self.of_dna(strand)
strand.tr('CGTA', 'GCAU')
end
Run Code Online (Sandbox Code Playgroud)
现在,如果您想进行快速测试以确保您实际处理的是有效序列:
def self.of_dna(strand)
return '' unless (strand.match(/\A[CGTA]*\z/))
strand.tr('CGTA', 'GCAU')
end
Run Code Online (Sandbox Code Playgroud)
你在这里遇到了一些其他坏习惯,比如当字符串在那个特定任务上更好的时候创建数组来保存单个字符.c = ''然后c << 'G'比数组版本更高效,特别是考虑到数组将包含N个字符串,每个字符串都带有一些开销,并且需要在最后使用创建另一个字符串join.使用Ruby时,尝试将临时或其他方面的计算所需的对象数量保持在最低限度.它通常更快,减少"垃圾".
| 归档时间: |
|
| 查看次数: |
741 次 |
| 最近记录: |