5

In ruby I could do this:

def DNA_strand(dna)
  base_hash = { 'A' => 'T', 'T' => 'A', 'G' => 'C', 'C' => 'G' }
  dna.gsub(/[ATGC]/, base_hash)
end

I could also do this which would be exactly equivalent:

def DNA_strand(dna)
  Dna.tr(’ACTG’, ’TGAC’)
end

In JS is there any equivalent method to :tr in ruby?

Currently I can only think of solving this problem in JS like this:

function DNAStrand(dna){
  function matchBase(match, offset, string) {
    const base = { 'A': 'T', 'T': 'A', 'G': 'C', 'C': 'G' };
    return `${base[match]}`;
  }
  return dna.replace(/[ATGC]/g, matchBase);
}

Any comments will be appreciated!

Richard Jarram
  • 899
  • 11
  • 22
  • 2
    btw, `return base[match];` is enough. – Nina Scholz Nov 02 '19 at 20:24
  • 3
    nothing built-in, but you can shorten your replace to `dna.replace(/[ATGC]/g, m => base[m])` which is only a tiny bit longer than the ruby version. – georg Nov 02 '19 at 20:29
  • 5
    Here's the doc for Ruby's method [String#tr](https://ruby-doc.org/core-2.6.3/String.html#method-i-tr). I expect anyone who does not know Ruby will want to read that before venturing an answer. – Cary Swoveland Nov 02 '19 at 21:45

1 Answers1

1

JavaScript has no built in .tr function, but you can add a prototype to the String object so that you can use a dna.tr('ACTG', 'TGAC'):

String.prototype.tr = function(from, to) {
  let trMap = {};
  from.split('').forEach((f, i) => {
    trMap[f] = to[i] || to[to.length-1];
  });
  return this.replace(/./g, ch => trMap[ch] || ch);
};

const from = 'ACTG';
const to   = 'TGAC';

[
  'ATGC',
  'GCAT',
  'ATXY'
].forEach(dna => {
  console.log(dna + ' => ' + dna.tr(from, to));
});
Output:
ATGC => TACG
GCAT => CGTA
ATXY => TAXY
Peter Thoeny
  • 7,379
  • 1
  • 10
  • 20