Trust me when I say that Computer Science is awesome and amazing! There is almost always more than one way to come to a solution to a given problem.
In this tutorial, we will learn how to solve the Free Code Camp DNA Pairing Challenge in five different ways.
Each DNA molecule is made up of two strands, and there are four nucleotides present in DNA: Adenine
, Cytosine
, Thymine
, and Guanine
. Each of the nucleotides on one side of the strand pairs up with a specific nucleotide on the other side of the strand. For example, if there’s a G
on one side of the strand, there will always be a C
on the other, and vice versa. If there’s a T
on one side of the strand, there will always be an A
on the other, and vice versa.
In this challenge, we are interested in finding the missing nucleotides on the other side of the strand.
For example, the string GCG
represents one strand of the DNA. The missing pair elements on the other strand are CGC
. Hence, as a result, we will return a 2D array made of arrays of pair elements grouped into one encapsulating array: [[“G”, “C”], [“C”,“G”],[“G”, “C”]]
.
The DNA strand is missing the pairing element. Take each character, get its pair, and return the results as a 2D array. Base pairs are a pair of
AT
andCG
. Match the missing element to the provided character. Return the provided character as the first element in each array. For example, for the inputGCG
, return[["G", "C"], ["C","G"],["G", "C"]]
. The character and its pair are paired up in an array, and all the arrays are grouped into one encapsulating array.
function pairElement(str) {
return str;
}
pairElement("GCG");
[["A","T"],["T","A"],["C","G"],["G","C"],["A","T"]]
[["T","A"],["T","A"],["G","C"],["A","T"],["G","C"]]
[["C","G"],["T","A"],["C","G"],["T","A"],["A","T"]]
As we may have read in the challenge description above, the goal of this exercise is to return the missing strand in a 2D array. In biology class, we learned about DNA base pairs (Need a refresher? Wikipedia is your friend). They are A-T and C-G, and they go both ways. So, every time we have:
for
loop and if
statementFor this solution, we will loop over the parameter that is passed to the function and use an if
statement to return the correct pair.
function pairElement(str) {
// Step 1. Declare the variable of type array that will encapsulate other paired arrays
const arrDNA = [];
// Step 2. Create the FOR loop with initializer less then str.length
for (let i = 0; i < str.length; i += 1) {
// Step 3. Use if statement to evaluate baise pair and push it to arrDNA
if (str[i] === 'A') arrDNA.push([str[i], 'T']);
if (str[i] === 'T') arrDNA.push([str[i], 'A']);
if (str[i] === 'C') arrDNA.push([str[i], 'G']);
if (str[i] === 'G') arrDNA.push([str[i], 'C']);
}
/* Here "GCG"'s length equals 3
For each iteration: i = 0 and arrDNA = [[str[i], 'corresponding pair']]
First iteration: i = 0 arrDNA = [['G', 'C']]
Second iteration: i = 1 arrDNA = [['G', 'C'], ['C', 'G']]
Third iteration: i = 2 arrDNA = [['G', 'C'], ['C', 'G'], ['G', 'C']]
End of the FOR Loop*/
// Step 4. Return the 2D array
return arrDNA;
}
pairElement("GCG");
function pairElement(str) {
const arrDNA = [];
for (let i = 0; i < str.length; i += 1) {
if (str[i] === 'A') arrDNA.push([str[i], 'T']);
if (str[i] === 'T') arrDNA.push([str[i], 'A']);
if (str[i] === 'C') arrDNA.push([str[i], 'G']);
if (str[i] === 'G') arrDNA.push([str[i], 'C']);
}
return arrDNA;
}
pairElement("GCG");
function pairElement(str) {const arrDNA = [];for (let i = 0; i < str.length; i += 1) {if (str[i] === 'A') arrDNA.push([str[i], 'T']);if (str[i] === 'T') arrDNA.push([str[i], 'A']);if (str[i] === 'C') arrDNA.push([str[i], 'G']);if (str[i] === 'G') arrDNA.push([str[i], 'C']);}return arrDNA;}console.log(pairElement("GCG"));
for
loop, charAt()
method, and if
statementIn this solution, we will make use of the traditional for
loop and if
statements once more, in combination with the String
object’s charAt()
method. The charAt()
method (String.prototype.charAt()
) returns the character at the specified index in a string.
function pairElement(str) {
// Step 1. Create an empty array that will encapsulate other paired arrays
const arrDNA = [];
// Step 2. Iterate through the str with a FOR loop
for (let i = 0; i < str.length; i += 1) {
// Step 3. Use if statement to evaluate base pair and push it to arrDNA
// If the current str character is X create an array of current str with its corresponding pair and push the array to arrDNA
if (str.chartAt(i) === 'A') // if A
arrDNA.push([str[i], 'T']); // ...push [A - T]
else if (chartAt(i) === 'T') // if T
arrDNA.push([str[i], 'A']); //...push [T - A]
else if (chartAt(i) === 'C') // if C
arrDNA.push([str[i], 'G']); // ...push [C - G]
else if (chartAt(i) === 'G') // if G
arrDNA.push([str[i], 'C']); // ...push [G - C]
}
// Step 4. Return the 2D array
return arrDNA;
}
pairElement("GCG");
function pairElement(str) {
const arrDNA = [];
for (let i = 0; i < str.length; i += 1) {
if (str.chartAt(i) === 'A')
arrDNA.push([str[i], 'T']);
else if (chartAt(i) === 'T')
arrDNA.push([str[i], 'A']);
else if (chartAt(i) === 'C')
arrDNA.push([str[i], 'G']);
else if (chartAt(i) === 'G')
arrDNA.push([str[i], 'C']);
}
return arrDNA;
}
pairElement("GCG");
function pairElement(str) {const arrDNA = [];for (let i = 0; i < str.length; i += 1) {if (str.chartAt(i) === 'A')arrDNA.push([str[i], 'T']);else if (chartAt(i) === 'T')arrDNA.push([str[i], 'A']);else if (chartAt(i) === 'C')arrDNA.push([str[i], 'G']);else if (chartAt(i) === 'G')arrDNA.push([str[i], 'C']);}return arrDNA;}console.log(pairElement("GCG"));
for...of
The for...of
creates a loop iterating over iterable objects (built-in string, array, and array-like objects).
function pairElement(str) {
// Step 1. Create an empty array that will encapsulate other paired arrays
const arrDNA = [];
// Step 2. Create an object of base pair
const basePair = {
'A': 'T',
'T': 'A',
'C': 'G',
'G': 'C'
}
// Step 3. Iterate through the str with a for of loop
for (const letter of str) {
// Step 4. Create an array of letter with its corresponding pair and push to arrDNA
arrDNA.push([letter, basePair[letter]]);
}
// Step 5. Return the 2D array
return arrDNA;
}
pairElement("GCG");
function pairElement(str) {
const arrDNA = [];
const basePair = {
'A': 'T',
'T': 'A',
'C': 'G',
'G': 'C'
}
for (const letter of str) {
arrDNA.push([letter, basePair[letter]]);
}
return arrDNA;
}
pairElement("GCG");
function pairElement(str) {const arrDNA = [];const basePair = {'A': 'T','T': 'A','C': 'G','G': 'C'}for (const letter of str) {arrDNA.push([letter, basePair[letter]]);}return arrDNA;}console.log(pairElement("GCG"));
split
and map
Let’s try to resolve this problem using the String.prototype.split()
and the Array.prototype.map()
method. The String.prototype.split()
method (split()
) is used to convert a string into an array. The map()
method creates a new array with the results of calling a function for every array element.
function pairElement(str) {
// Step 1. Create an object of base pair
const basePair = {
'A': 'T',
'T': 'A',
'C': 'G',
'G': 'C'
}
// Step 2. convert the str into an array with split and store the result into arrStr variable
const arrStr = str.split('');
/* Step 3. Map through the arrStr and return an array of current value and it baise
Keep the result of mapping under arrDNA variable
*/
const arrDNA = arrStr.map(letter => [letter, basePair[letter]])
// Step 4. Return the 2D array
return arrDNA;
}
pairElement("GCG");
function pairElement(str) {
const basePair = {
'A': 'T',
'T': 'A',
'C': 'G',
'G': 'C'
}
const arrStr = str.split('');
const arrDNA = arrStr.map(letter => [letter, basePair[letter]])
return arrDNA;
}
pairElement("GCG");
Or, even better, we use the split()
map()
method in one line:
function pairElement(str) {
const basePair = {
'A': 'T',
'T': 'A',
'C': 'G',
'G': 'C'
}
return str.split('').map(letter => [letter, basePair[letter]]);
}
pairElement("GCG");
function pairElement(str) {const basePair = {'A': 'T','T': 'A','C': 'G','G': 'C'}return str.split('').map(letter => [letter, basePair[letter]]);}console.log(pairElement("GCG"));
Split
, forEach
, and switch
In this solution, we will use the split()
, forEach()
, and switch
methods. We have already discussed the split()
method in another solution above. Let’s talk a bit about the remaining two:
array.forEach()
: This method executes a provided function once for each array element.switch
: This method is similar to the if
statement, but it gives a more descriptive way to compare a value with multiple variants.function pairElement(str) {
// Step 1. Create an empty array that will encapsulate other paired arrays
const arrDNA = [];
// Step 2. convert the str into an array with split and store the result into arrStr variable
const arrStr = str.split('');
// Step 3. Loop through arrStr using forEach
arrStr.forEach(x => {
/* Step 4. Use switch statement to test x and push the corresponding array to arrDNA */
switch (x) {
case "G": // in case x = G
arrDNA.push(["G","C"]); // ...push ["G","C"] to arrDNA
break // break tells the script to run from the case where the criterion is met
case "C":
arrDNA.push(["C","G"]);
break;
case "T":
arrDNA.push(["T","A"]);
break;
case "A":
arrDNA.push(["A","T"]);
break;
}
});
// Step 5. Return the 2D array
return arrDNA;
}
pairElement("GCG");
function pairElement(str) {
const arrDNA = [];
const arrStr = str.split('');
arrStr.forEach(x => {
switch (x) {
case "G":
arrDNA.push(["G","C"]);
break
case "C":
arrDNA.push(["C","G"]);
break;
case "T":
arrDNA.push(["T","A"]);
break;
case "A":
arrDNA.push(["A","T"]);
break;
}
});
return arrDNA;
}
pairElement("GCG");
That is it for this tutorial. We used five different ways to solve the DNA pairing challenge that is available on FreeCodeCamp.
Which of these solutions appeals to you the most? Do you have any other solutions in mind? Share them with us! If I had to choose just one solution from all the ones mentioned above, I’d go for the 3rd one that makes use of for...of
.
function pairElement(str) {const arrDNA = [];const arrStr = str.split('');arrStr.forEach(x => {switch (x) {case "G":arrDNA.push(["G","C"]);breakcase "C":arrDNA.push(["C","G"]);break;case "T":arrDNA.push(["T","A"]);break;case "A":arrDNA.push(["A","T"]);break;}});return arrDNA;}console.log(pairElement("GCG"));
Free Resources