我有将RNA序列翻译成蛋白质的代码。我的问题是我应该在哪里抛出错误?检查完所有测试后,代码应引发错误。我的问题是,如果我在else if (rnaSequence[i] != key) throw new Error ('Invalid codon');上抛出错误,则不会评估所有其他测试。

...

let obj = {
  AUG: 'Methionine',
  UUU: 'Phenylalanine',
  UUC: 'Phenylalanine',
  UUA: 'Leucine',
  UUG: 'Leucine',
  UCU: 'Serine',
  UCC: 'Serine',
  UCA: 'Serine',
  UCG: 'Serine',
  UAU: 'Tyrosine',
  UAC: 'Tyrosine',
  UGU: 'Cysteine',
  UGC: 'Cysteine',
  UGG: 'Tryptophan',
  UAA: 'STOP',
  UAG: 'STOP',
  UGA: 'STOP'
};

const translate = (str) => {
  let rnaSequence = (str == null) ? null : str.match(/[A-Z]{1,3}/g);
  let proteinArr = [];

  for (let [key, value] of Object.entries(obj)) {
    if (rnaSequence == null) return proteinArr;
    else if (rnaSequence[0] == key) proteinArr.unshift(value);
    else for (let i = 1; i <= rnaSequence.length; i++) {
      if (rnaSequence[i] == key) proteinArr.push(value);
      // else if (rnaSequence[i] != key) throw new Error ('Invalid codon');
    }
  }

  for (let j = 0; j <= proteinArr.length; j++) {
    if (proteinArr[j] == "STOP") proteinArr.splice(j);
  }
  return proteinArr;
};
...


These are my tests:
...
 test('Small RNA strand', () => {
    expect(translate('AUGUUUUCU')).toEqual(['Methionine', 'Phenylalanine', 'Serine']);
  });

  xtest('Invalid codon throws error', () => {
    expect(() => translate('LOL')).toThrow(new Error('Invalid codon'));
  });

  xtest('Invalid codon throws error', () => {
    expect(() => translate('AUGOO')).toThrow(new Error('Invalid codon'));
  });

...

最佳答案

您正在针对对象中的每个键运行此命令:

else if (rnaSequence[i] != key)

假设您的RNA序列为:
"AUGUUUUCU"

这被翻译成数组:
["AUG", "UUU", "UCU"]

然后,您遍历对象中的每个键值对(即对象的条目)。第一个key"AUG"。您的第一个if条件为false,但将执行以下if条件:
else if (rnaSequence[0] == key) proteinArr.unshift(value);

因为rnaSequence[0]拥有"AUG",并且key也等于"AUG"。现在,这将导致您的RNA阵列看起来像:
["Methionine", "AUG", "UCU", "UUU"]

因为.unshift(value)会将键的关联值添加到数组中。然后,继续进行对象中的下一个键/值对。这次是UUU: 'Phenylalanine'。在第二次迭代中,您再次查看if语句。第一个if条件是false,第二个也是false,因为"Methionine"不等于键"UUU"。因此,您的第三个if条件将为true,因此将引发您的错误。

如果要修复代码,可以创建一个results数组。可以在结果数组上使用unshift(),而不是在RNA数组上使用.push()。在抛出任何错误之前,还需要遍历对象中的所有键,以确定RNA蛋白是否不在对象中。

但是,我认为,最简单的方法就是重新考虑您的方法。当前,您正在遍历对象,以查看您的对象中是否存在RNA蛋白并获得其相关的蛋白值。通过使用 key in obj hasOwnProperty 或简单地使用bracket notation索引对象,有更好的方法。

我建议您像现在一样,从原始字符串中获取RNA序列阵列。然后,在此数组上使用 .map() 通过在对象中查找将每个字符串映射到与其关联的蛋白质:
"AUGUUUUCU" ---> ["AUG", "UUU", "UCU"] ---> ['Methionine', 'Phenylalanine', 'Serine']

您还可以通过使用 .every() 进行检查,以检查数组中的每个RNA链在obj中是否具有键值对。

请参见下面的示例:

const obj = { AUG: 'Methionine', UUU: 'Phenylalanine', UUC: 'Phenylalanine', UUA: 'Leucine', UUG: 'Leucine', UCU: 'Serine', UCC: 'Serine', UCA: 'Serine', UCG: 'Serine', UAU: 'Tyrosine', UAC: 'Tyrosine', UGU: 'Cysteine', UGC: 'Cysteine', UGG: 'Tryptophan', UAA: 'STOP', UAG: 'STOP', UGA: 'STOP' };

const translate = str => {
  const rnaSequence = (str == null) ? null : str.match(/[A-Z]{1,3}/g);
  if(!rnaSequence)
    return "Invalid codon"; // throw here instead: throw new Error ('Invalid codon');

  const allValid = rnaSequence.every(key => key in obj); // check all keys in object
  if(!allValid)
    return "Invalid codon"; // throw here instead: throw new Error ('Invalid codon');

  return rnaSequence.map(key => obj[key]);
}

console.log(translate('AUGUUUUCU')) // ['Methionine', 'Phenylalanine', 'Serine']);

console.log(translate('LOL')) // new Error('Invalid codon')
console.log(translate('AUGOO')) // new Error('Invalid codon')

关于javascript - 有人可以帮我弄清楚我的代码有什么问题吗?它将RNA序列翻译成蛋白质,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60105598/

10-10 14:50