This function takes a string of DNA such as 'GTCA' and returns an array containing correctly matched DNA pairs.
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;
}
This is correct. However i'm trying to find a shorter, simpler way of writing it. Can anyone help me with what I should be using?
You can improve you code in following steps:
toLowerCase()
on input.split
the string and map()
it rather than creating an array push()
values into it.function pairDNA(dna) {
const obj = {
c: 'CG',
g: 'GC',
t: 'TA',
a: "AT"
}
return dna.split('').map(x => obj[x.toLowerCase()])
}
If the string could contain anything other the specific letters then you need to filter()
the undefined
values after map
return dna.split('').map(x => obj[x.toLowerCase()]).filter(x => x !== undefined)
Another better is mentioned by @RobG in the comments that we can remove the unwanted letters from string before looping through it.
return dna
.toLowerCase()
.replace(/[^cgta]/g,'')
.split('')
.map(x => obj[x])
I'd probably:
Use a for-of
loop (or possibly mapping with possible filtering)
Use a lookup object or Map
Make the string lower or upper case when switching/looking up (but duplicated entries in the switch/lookup work too):
If you know that dna
will only ever contain c
/C
, g
/G
, t
/T
/, or a
/A
(which, as I understand it, is true of DNA ;-) ), then you can use Array.from
with its mapping feature with a lookup object/Map:
const table = {
c: "CG",
g: "GC",
t: "TA",
a: "AT"
};
function pairDNA(dna) {
return Array.from(dna, entry => table[entry.toLowerCase()]);
}
I'm using Array.from
because it will split the string on code points, not just code units (doesn't break up surrogate pairs) and has a mapping feature if you provide a mapping function. (Basically, Array.from(str, mappingFunction)
is [...str].map(mappingFunction)
but without the intermediate array.) Probably not all that relevant here given the content of your string, but can matter if your string may contain surrogate pairs.
Or with a 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()));
}
If you can't make that assumption, add .filter
to filter out the ones that didn't have a match:
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);
}
Or if you want to avoid creating the extra array the filter
would create, stick with for-of
(or even your 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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With