Switching variables in a function based on user input

66 Views Asked by At

I am trying to compare two DNA sequences with wobbles and report mismatches. To explain DNA and wobbles in programming sense, they are strings of characters(bases) A,T,C and G and wobbles are characters assigned to more than one bases e.g. R is 'A' or 'G'.
Here !N in if() condition corresponds to the declared array N. I have to manually edit this each time to change it to !R, !Y, or !K etc in the condition.

const R = ['A', 'G'];
const Y = ['C', 'T'];
const K = ['G', 'T'];
const N = ['A', 'G', 'C', 'T'];
const wob = ['R', 'Y', 'K', 'M', 'S', 'W', 'N']

let mismatchPositions = [];
for (let i = 0; i < referenceLength; i++) {
  if (!N.includes(seq.sequence[i]) && wob.includes(referenceSeq[i]) &&
    referenceSeq[i] !== seq.sequence[i]) {
    const mismatch = `(${i+1} ${referenceSeq[i]} > ${seq.sequence[i]})`;
    mismatchPositions.push(mismatch);
  } else if (!wob.includes(referenceSeq[i]) && referenceSeq[i] !== seq.sequence[i]) {
    const mismatch = `(${i+1} ${referenceSeq[i]} > ${seq.sequence[i]})`;
    mismatchPositions.push(mismatch);
  }

I tried putting all the arrays in one variable with flat() but it loses its functionality because there are same bases in few of the wobbles. Is there any way to individually switch the arrays in if() condition from !N to !R and so. I want it make as a user input variable.

Example: for reference sequence:

GTAAGTTGNACG

Output:

GTAAGTTGAATG -(11 C > T Mismatch)
GTAAGTTAAACG -(8 G > A Mismatch)

For Mismatch at N it is not showing any mismatch because of the if() condition. If the ref-seq had Y or K instead of N it would show mismatch at 9th position.

2

There are 2 best solutions below

1
James On

You can declare an object containing the RYKN arrays:

const rykn  = {
  R: ['A', 'G'],
  Y: ['C', 'T'],
  K: ['G', 'T'],
  N: ['A', 'G', 'C', 'T']
};

As long as you have some string variable containing which of "R", "Y", "K", "N" to use, you can modify your if:

if (!N.includes(seq.sequence[i] && ...)

to

let choice = "R"; // or use a value from a drop down, etc
if (!rykn[choice].includes(seq.sequence[i] && ...)
1
Nina Scholz On

You could put the bases into an object and iterate the keys.

const
    compare = (sequence, reference) => {
        const
            bases = { R: 'AG', Y: 'CT', K: 'GT', N: 'AGCT' },
            wob = 'RYKMSWN';

        let mismatchPositions = {};
        for (let i = 0; i < reference.length; i++) {
            if (reference[i] === sequence[i]) continue;
            for (const base in bases) {
                if (!bases[base].includes(sequence[i]) && wob.includes(reference[i])) {
                    (mismatchPositions[base] ??= []).push(`(${i + 1} ${reference[i]} > ${sequence[i]})`);
                }
            }
            if (!wob.includes(reference[i])) {
                (mismatchPositions.wob ??= []).push(`(${i + 1} ${reference[i]} > ${sequence[i]})`);
            }
        }
        return mismatchPositions;
    };
    
console.log(compare('GTAAGTTGAATG', 'GTAAGTTGNACG'));
console.log(compare('GTAAGTTAAACG', 'GTAAGTTGNACG'));
.as-console-wrapper { max-height: 100% !important; top: 0; }