如何改善和缩短这段代码?[关闭]


9

此函数采用一串DNA(例如“ GTCA”)并返回包含正确匹配的DNA对的数组。

function pairDNA(dna) {

  const pairs = []

  for (let i = 0; i < dna.length; i ++) {

    if (dna[i] === "C" | dna[i] === "c") {
      pairs.push("CG");
    } else if (dna[i] === "G"| dna[i] === "g") {
      pairs.push("GC");
    } else if (dna[i] === "T"| dna[i] === "t") {
    pairs.push("TA");
    } else if (dna[i] === "A"| dna[i] === "a") {
      pairs.push("AT");
    }
  }

return pairs;
}

这是对的。但是,我正在尝试找到一种更短,更简单的书写方式。谁能帮助我使用我应该使用的东西?


1
轻松使用此方法dna [i] .toLowerCase()
Thaier Alkhateeb

9
如果您的代码有效并且只想进行改进,请尝试codereview.stackexchange.com
Peter Collingridge

我认为此代码无法按预期工作,| 也不可以在Javascript中执行逻辑或||
Ma'moun othman

2
@mamounothman-是的,但是两者都可以在该代码中工作(不过||会更好)。
TJ Crowder

Answers:


14

您可以按照以下步骤改进代码:

  • 当有多个if语句并且所有结构都具有相同的结构时,您可能需要使用一个对象
  • 您需要检查大写和小写。只需toLowerCase()在输入上使用。
  • 您可以split使用字符串及其字符串,map()而不是在其中创建数组push()值。

function pairDNA(dna) {
  const obj = {
    c: 'CG',
    g: 'GC',
    t: 'TA',
    a: "AT"
  }
  return dna.split('').map(x => obj[x.toLowerCase()])

}

如果字符串可以包含其他任何特定的字母,那么您需要输入filter()以下undefinedmap

return dna.split('').map(x => obj[x.toLowerCase()]).filter(x => x !== undefined)

@RobG在注释中提到了另一个更好的方法,我们可以在循环之前从字符串中删除不需要的字母。

return dna
        .toLowerCase()
        .replace(/[^cgta]/g,'')
        .split('')
        .map(x => obj[x])

1
如果dna包含未列出的字符,则undefined您的最终数组中将包含值。
了GrégoryNEUT

1
@GrégoryNEUT在我的答案中为该情况添加了一个解决方法
Maheer Ali

或者,您可以使用预处理字符串dna.toLowerCase().replace(/[^cgta]/g,'')...。;-)
RobG

@RobG真的很喜欢。我添加了我的答案。
Maheer Ali

1
我错过了那是一个字符串。:-) FWIW,现在是一种更Unicode友好的将字符串拆分为数组的方法[...dna]。它不会分解代理对。(或者Array.from,这就是如果你要映射特别有用Array.from(dna, mappingFunction)。)(并非所有相关在这里,我想dna仅包含cgt,和a。)
TJ克罗德

3

我可能会:

  1. 使用for-of循环(或可能的映射以及可能的过滤)

  2. 使用查找对象或地图

  3. 切换/查找时,使字符串为小写或大写(但切换/查找中的重复条目也起作用):

如果您知道它们dna仅包含c/ Cg/ Gt/ T/或a/ A(据我所知,对DNA是正确的;-)),那么可以将Array.from其映射功能与查找对象/ Map一起使用:

const table = {
    c: "CG",
    g: "GC",
    t: "TA",
    a: "AT"
};

function pairDNA(dna) {
  return Array.from(dna, entry => table[entry.toLowerCase()]);
}                                                                                                                           

我使用Array.from它是因为它将在代码点上分割字符串,而不仅仅是代码单元(不会分解代理对),并且如果提供映射功能,则具有映射功能。(基本上Array.from(str, mappingFunction)[...str].map(mappingFunction),但没有中间阵列。)也许不是所有的,在这里给出相关的字符串的内容,但是能够决定的事情,如果你的字符串可能包含代理对。

或搭配Map

const table = new Map([
  [c, "CG"],
  [g, "GC"],
  [t, "TA"],
  [a, "AT"]
]);

function pairDNA(dna) {
  return Array.from(dna, entry => table.get(entry.toLowerCase()));
}                                                                                                                           

如果您无法做出此假设,请添加.filter以过滤掉不匹配的内容:

function pairDNA(dna) {
  return Array.from(dna, entry => table.get(entry.toLowerCase())).filter(Boolean);
  // or if using an object: return dna.map(entry => table[entry.toLowerCase()]).filter(Boolean);
}

或者,如果您想避免创建将要创建的额外数组filter,请坚持使用for-of(甚至是您的for):

const table = {
    c: "CG",
    g: "GC",
    t: "TA",
    a: "AT"
};

function pairDNA(dna) {
  const pairs = [];

  for (const entry of dna) {
    const value = table[entry.toLowerCase()];
    if (value) {
      pairs.push(value);
    }
  }
  return pairs;
}

2

您可以使用查找映射来简化循环:

function pairDNA(dna) {

  const pairs = [], key = { G: "GC", C: "CG", A: "AT", T: "TA" };

  for (let i = 0; i < dna.length; i ++)
    pairs.push(key[dna[i].toUpperCase()]);
  return pairs;
}

有趣的是我没想到要这样做,谢谢!
CocoFlade

2

也许不会缩短,但绝对可以维护。

function pairDNA(dna) {
  const map = {
    C: 'CG',
    c: 'CG',
    G: 'GC',
    g: 'GC',
    T: 'TA',
    t: 'TA',
    A: 'AT',
    a: 'AT',
  };

  return dna.split('').reduce((tmp, x) => {
    if (map[x]) {
      tmp.push(map[x]);
    }

    return tmp;
  }, []);
}

您也可以这样做:

function pairDNA(dna) {
  const map = {
    c: 'CG',
    g: 'GC',
    t: 'TA',
    a: 'AT',
  };

  return dna.split('').reduce((tmp, x) => {
    if (map[x].toLowerCase()) {
      tmp.push(map[x]);
    }

    return tmp;
  }, []);
}

2

您可以尝试使用switch caseforEach函数,如下所示:

function pairDNA(dna) {
  let pairs = [];

  dna.forEach( dnaValue => {
    switch (dnaValue.toLowerCase()) {
      case "c":
        pairs.push("CG");
        break;
      case "g":
        pairs.push("GC");
        break;
      case "t":
        pairs.push("TA");
        break;
      case "a":
        pairs.push("AT");
        break;
    }
  })

  return pairs;
}

1

您可以将字符串小写,这将使您删除大写字符串的检查:

function pairDNA(dna) {
  dna = dna.toLowerCase();
  const pairs = []
  for (let i = 0; i < dna.length; i ++) {
   if (dna[i]=== "c") {
     pairs.push("CG");
   } else if (dna[i]dna[i] === "g") {
     pairs.push("GC");
   } else if (dna[i] === "t") {
     pairs.push("TA");
   } else if (dna[i] === "a") {
     pairs.push("AT");
   }
 }

 return p;
}

1
const lookup = {
    c: "CG", 
    g: "GC", 
    t: "TA", 
    a: "AT"
};

function pairDNA(dna) {  

  const pairs = [];

  for (let i = 0; i < dna.length; i ++) {
     pairs.push( lookup[dna[i].toLowerCase()] );
  }

  return pairs;

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.