이 코드 블록을 어떻게 개선하고 단축시킬 수 있습니까? [닫은]


9

이 함수는 'GTCA'와 같은 DNA 문자열을 가져와 정확하게 일치하는 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

9
코드가 작동하고 개선이 필요한 경우 codereview.stackexchange.com
Peter Collingridge

나는이 코드가 의도 한대로 작동하지 않는다고 생각하고 다음 | 과 같은 자바 스크립트에서 논리적 OR을하지 않는다||
Ma'moun othman

2
@mamounothman-사실이지만 둘 다 해당 코드에서 작동합니다 ( ||그러나 더 좋을 것입니다).
TJ Crowder

답변:


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

1
@ GrégoryNEUT 내 답변에 해당 사례에 대한 수정 사항 추가
Maheer Ali

또는을 사용하여 문자열을 사전 처리 할 수 ​​있습니다 dna.toLowerCase().replace(/[^cgta]/g,'').... ;-)
RobG

@RobG 정말 마음에 들었습니다. 나는 대답을 덧붙였다.
Maheer Ali

1
나는 그것이 끈이라는 것을 놓쳤다. :-) FWIW, 문자열을 배열로 나누는 더 유니 코드 친화적 인 방법입니다 [...dna]. 대리 쌍을 분리하지 않습니다. (또는 Array.from, 당신은 매핑려고하는 경우에 특히 유용하다 : Array.from(dna, mappingFunction).) (여기 관련, 나는 가정의 모든 것을하지 dna만 포함 c, g, t,와 a.)
TJ 크라우

3

아마 것입니다 :

  1. for-of루프를 사용하십시오 (또는 가능한 필터링으로 맵핑 가능)

  2. 조회 오브젝트 또는 맵 사용

  3. 전환 / 조회 할 때 문자열을 소문자 또는 대문자로 만듭니다 (그러나 전환 / 조회에서 중복 된 항목도 작동 함).

/ , / , / / 또는 / dna만 포함 한다는 것을 알고 있다면 (내가 이해하는 것처럼 DNA ;-)) 조회 객체 /지도와 함께 매핑 기능과 함께 사용할 수 있습니다 .cCgGtTaAArray.from

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 case과 같이 a 및 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;

}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.