Làm thế nào tôi có thể cải thiện và rút ngắn khối mã này? [đóng cửa]


9

Hàm này lấy một chuỗi DNA như 'GTCA' và trả về một mảng chứa các cặp DNA khớp chính xác.

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;
}

Chính xác. Tuy nhiên tôi đang cố gắng tìm một cách viết ngắn hơn, đơn giản hơn. Bất cứ ai có thể giúp tôi với những gì tôi nên sử dụng?


1
sử dụng dễ dàng phương pháp này dna [i] .toLowerCase ()
Thaier Alkhateeb

9
Nếu mã của bạn hoạt động và bạn chỉ muốn cải thiện, hãy thử codereview.stackexchange.com
Peter Collingridge

Tôi không nghĩ mã này hoạt động như dự định, | không làm logic HOẶC như Javascript||
Ma'moun othman

2
@mamounothman - Điều đó đúng, nhưng cả hai sẽ hoạt động trong mã đó ( ||mặc dù sẽ tốt hơn).
TJ Crowder

Câu trả lời:


14

Bạn có thể cải thiện mã của mình theo các bước sau:

  • Khi có nhiều câu lệnh if và tất cả đều có cùng cấu trúc, có lẽ bạn cần sử dụng một đối tượng
  • Bạn cần kiểm tra cả chữ hoa và chữ thường. Chỉ cần sử dụng toLowerCase()trên đầu vào.
  • Bạn có thể splitchuỗi và map()nó thay vì tạo một push()giá trị mảng vào nó.

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

}

Nếu chuỗi có thể chứa bất cứ thứ gì khác ngoài các chữ cái cụ thể thì bạn cần filter()các undefinedgiá trị saumap

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

Một điều tốt hơn được đề cập bởi @RobG trong các bình luận rằng chúng ta có thể xóa các chữ cái không mong muốn khỏi chuỗi trước khi lặp qua nó.

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

1
Nếu dna chứa một ký tự không được liệt kê, bạn sẽ có undefinedcác giá trị trong mảng cuối cùng của bạn.
Grégory CẦN

1
@ GrégoryNEUT Đã thêm một bản sửa lỗi cho trường hợp đó trong câu trả lời của tôi
Maheer Ali

Hoặc bạn có thể xử lý trước chuỗi dna.toLowerCase().replace(/[^cgta]/g,'').... ;-)
RobG

@RobG Thực sự thích điều đó. Tôi đã thêm nó yo câu trả lời của tôi.
Maheer Ali

1
Tôi nhớ rằng đó là một chuỗi. :-) FWIW, một cách phân tách chuỗi thân thiện với Unicode hơn hiện nay là [...dna]. Nó không chia tay cặp thay thế. (Hoặc Array.from, đó là đặc biệt hữu ích nếu bạn đang đi để lập bản đồ: Array.from(dna, mappingFunction).) (Không phải tất cả mà liên quan ở đây, tôi giả sử dnachỉ chứa c, g, t, và a.)
TJ Crowder

3

Tôi có thể:

  1. Sử dụng một for-ofvòng lặp (hoặc có thể ánh xạ với khả năng lọc)

  2. Sử dụng một đối tượng tra cứu hoặc Bản đồ

  3. Đặt chuỗi chữ thường hoặc chữ hoa khi chuyển đổi / tra cứu (nhưng các mục trùng lặp trong công tắc / tra cứu cũng hoạt động):

Nếu bạn biết rằng dnasẽ chỉ bao giờ chứa c/ C, g/ G, t/ T/ hoặc a/ A(trong đó, như tôi hiểu nó, đúng với DNA ;-)), sau đó bạn có thể sử dụng Array.fromvới tính năng lập bản đồ của mình với một đối tượng tra cứu / Bản đồ:

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

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

Tôi đang sử dụng Array.fromvì nó sẽ phân tách chuỗi trên các điểm mã , không chỉ các đơn vị mã (không phá vỡ các cặp thay thế) và có tính năng ánh xạ nếu bạn cung cấp chức năng ánh xạ. (Về cơ bản, Array.from(str, mappingFunction)[...str].map(mappingFunction)nhưng không có mảng trung gian.) Có lẽ không phải tất cả những gì liên quan ở đây đưa ra nội dung của chuỗi của bạn, nhưng có thể có vấn đề nếu chuỗi bạn có thể chứa cặp thay thế.

Hoặc với một 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()));
}                                                                                                                           

Nếu bạn không thể đưa ra giả định đó, hãy thêm .filtervào để lọc ra những cái không khớp:

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);
}

Hoặc nếu bạn muốn tránh tạo mảng bổ sung, bạn filtersẽ tạo, gắn bó với for-of(hoặc thậm chí là của bạn 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

Bạn có thể sử dụng ánh xạ tra cứu để đơn giản hóa vòng lặp:

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;
}

Điều đó thật thú vị Tôi đã không nghĩ làm theo cách này, cảm ơn bạn!
CocoFlade

2

Có thể không rút ngắn nhưng chắc chắn dễ bảo trì hơn.

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;
  }, []);
}

Bạn cũng có thể làm:

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

Bạn có thể thử sử dụng một switch casevà một chức năng forEach, như thế này:

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

Bạn có thể viết thường chuỗi sẽ cho phép bạn loại bỏ việc kiểm tra chuỗi vốn:

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;

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.