Як я можу вдосконалити та скоротити цей блок коду? [зачинено]


9

Ця функція приймає рядок ДНК, такий як "GTCA", і повертає масив, що містить правильно підібрані пари ДНК.

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
Пітер Коллінгрідж

Я не думаю, що цей код працює за призначенням, | не робить логічного АБО у Javascript, як||
ROOT

2
@mamounothman - Це правда, але обидва будуть працювати в цьому коді ( ||було б краще, хоча).
TJ Crowder

Відповіді:


14

Ви можете вдосконалити код, виконавши наступні кроки:

  • Коли є декілька, якщо заяви і всі мають однакову структуру, вам, ймовірно, потрібно використовувати об'єкт
  • Вам потрібно перевірити великі і малі літери. Просто використовуйте 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()в undefinedзначеннях післяmap

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égory NEUT

1
@ GrégoryNEUT У свою відповідь
додав

Або ви можете попередньо обробити рядок за допомогою dna.toLowerCase().replace(/[^cgta]/g,'').... ;-)
RobG

@RobG Дуже сподобалось. Я додав це, моя відповідь.
Maheer Ali

1
Я пропустив, що це струна. :-) FWIW, тепер є більш зручним для Unicode способом розбиття рядків на масиви [...dna]. Це не розбиває сурогатних пар. (Або Array.from, що особливо корисно , якщо ви збираєтеся на карту: Array.from(dna, mappingFunction)). (Не всі , що ставлення тут, я вважаю , dnaтільки містить c, g, tі a.)
TJ Crowder

3

Я, мабуть,:

  1. Використовуйте for-ofцикл (або можливо зіставлення з можливою фільтрацією)

  2. Використовуйте об’єкт пошуку або Мапу

  3. Зробіть рядок нижнього або верхнього регістру під час перемикання / пошуку (але також дублюються записи у перемикачі / пошуку):

Якщо ви знаєте, що dnaбуде містити лише коли-небудь c/ C, g/ G, t/ T/ або a/ A(що, наскільки я розумію, це стосується ДНК ;-)), тоді ви можете використовувати 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

Ви можете спробувати скористатись функцією a switch caseі forEachfuncion, як-от так:

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;

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.