如果某个字符传递给Ruby,则停止循环

时间:2017-01-06 19:43:53

标签: ruby

因此,我正致力于将DNA链转录为RNA链。我目前的代码如下:

class Complement
  def self.of_dna(str)
    dna_rna = { 'G' => 'C', 'C' => 'G', 'T' => 'A', 'A' => 'U' }
    rna = []
    str.scan(/[GCTA]/).each do |x|
      rna << dna_rna[x]
    end
    rna.join('')
  end
end

除了在一种情况下,它完美地运作。如果通过部分正确的DNA链,例如ACGTXXXCTTAA,我的方法会将DNA翻译成RNA,只留下X,给我UGCAGAAUU的结果,而不是""只是def test_dna_correctly_handles_partially_invalid_input # skip assert_equal '', Complement.of_dna('ACGTXXXCTTAA') end 。如何才能使循环失败并在收到与DNA无关的字母时退出?

编辑: 我试图通过的测试看起来像这样:

 1) Error:
ComplementTest#test_dna_correctly_handles_completely_invalid_input:
ArgumentError: ArgumentError
    /Users/LukasBarry/exercism/ruby/rna-transcription/rna_transcription.rb:6:in `block in of_dna'
    /Users/LukasBarry/exercism/ruby/rna-transcription/rna_transcription.rb:5:in `each'
    /Users/LukasBarry/exercism/ruby/rna-transcription/rna_transcription.rb:5:in `of_dna'
    rna_transcription_test.rb:43:in `test_dna_correctly_handles_completely_invalid_input'

我从下面尝试了@Holger Just的想法,并收到了这个错误:

1) Failure:
ComplementTest#test_dna_correctly_handles_partially_invalid_input [rna_transcription_test.rb:48]:
Expected: ""
  Actual: "UGCAGAAUU"

我从上述方法中得到的常见失败是:

{{1}}

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:4)

试试这个

class Complement
  def self.of_dna(str)
    return "" if str =~ /[^GCTA]/
    ...
  end
end

有趣的是,你甚至不需要循环来替换字符

str = 'GATTACA'
str.tr('ATCG', 'UAGC')
# => 'CUAAUGU'

只需要你。

答案 1 :(得分:1)

您还可以在正则表达式中匹配X并执行一些erorr处理(如果在字符串中找到它)。这看起来像这样:

class Complement
  def self.of_dna(str)
    dna_rna = { 'G' => 'C', 'C' => 'G', 'T' => 'A', 'A' => 'U' }
    rna = []
    str.scan(/[GCTAX]/).each do |x|
      return '' if x == 'X'
      rna << dna_rna[x]
    end
    rna.join('')
  end
end

答案 2 :(得分:1)

我更喜欢使用Hash#fetch,因为它会在不匹配的情况下为你引发KeyError,允许你编写更少的代码来验证输入(即防御性编程较少),我认为比聪明更有价值(在这种情况下我会推荐String#tr)。

class DNA
  TranslationMap = { 'G' => 'C', 'C' => 'G', 'T' => 'A', 'A' => 'U' }
  attr_reader :dna

  def initialize(dna)
    @dna = dna
  end

  def to_rna
    dna.each_char.map do |nucleotide|
      TranslationMap.fetch(nucleotide)
    end.join('')
  rescue KeyError
    return false
  end
end

随意调整在拯救错误以满足您的需求时会发生什么。我建议为调用者处理一个更具体的异常(例如DNA::InvalidNucleotide)。

使用中:

dna = DNA.new 'GCTA'
 # => #<DNA:0x007fc49e903818 @dna="GCTA"> 
dna.to_rna
 # => "CGAU" 
dna = DNA.new 'ACGTXXXCTTAA'
 # => #<DNA:0x007fc49f064800 @dna="ACGTXXXCTTAA"> 
dna.to_rna
 # => false