How can I create a two-way mapping in JavaScript, or some other way to swap out values?

With an extra internal object for reverse mapping. Best if we add a utility class ;) like this:

function TwoWayMap(map) {
   this.map = map;
   this.reverseMap = {};
   for(var key in map) {
      var value = map[key];
      this.reverseMap[value] = key;   
   }
}
TwoWayMap.prototype.get = function(key){ return this.map[key]; };
TwoWayMap.prototype.revGet = function(key){ return this.reverseMap[key]; };

Then you instantiate like this:

var twoWayMap = new TwoWayMap({
   '*' : '__asterisk__', 
    '%' : '__percent__',
   ....
});

Then, for using it:

twoWayMap.get('*')   //Returns '__asterisk__'
twoWayMap.revGet('__asterisk__')  //Returns '*'

EDIT: Equivalent with ES6 syntax

class TwoWayMap {
    constructor(map) {
       this.map = map;
       this.reverseMap = {};
       for(let key in map) {
          const value = map[key];
          this.reverseMap[value] = key;   
       }
    }
    get(key) { return this.map[key]; }
    revGet(key) { return this.reverseMap[key]; }
}

Usage is the same

Hope this helps. Cheers


Use two objects. One object contains the * -> _asterisk_ mapping, the other object contains _asterisk_ -> *.

var forwardMap = {'*': '__asterisk__', '%': '__percent__', ...};
var reverseMap = {};
for (var key in forwardMap) {
    if (forwardMap.hasOwnProperty(key)) {
        reverseMap[forwardMap[key]] = key;
    }
}

I'd just use a plain object:

var map = { '*': '__asterisk__', '__asterisk__': '*', .... }

If you don't want to have to write all those out, take a look at the implementation of underscore's _.invert(object) here