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 the following:
ES6 syntax (scroll down for ES5 syntax)
class TwoWayMap { constructor(map) { this.map = map; this.reverseMap = {}; for(const key in map) { const value = map[key]; this.reverseMap[value] = key; } } get(key) { return this.map[key]; } revGet(key) { return this.reverseMap[key]; }}
Then you instantiate like this:
const twoWayMap = new TwoWayMap({ '*' : '__asterisk__', '%' : '__percent__', ....});
Finally, to use it:
twoWayMap.get('*') //Returns '__asterisk__'twoWayMap.revGet('__asterisk__') //Returns '*'
Bonus: If you also need set/unset methods, you can do it (inside the class) easily like:
set(key, value) { this.map[key] = value; }unset(key) { delete this.map[key] }// same for set_reverse and unset_reverse, just use this.reverseMap instead
Equivalent with ES5 (old js) syntax:
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]; };
Usage is the same:
var twoWayMap = new TwoWayMap({ '*' : '__asterisk__', '%' : '__percent__', ....});twoWayMap.get('*') //Returns '__asterisk__'twoWayMap.revGet('__asterisk__') //Returns '*'
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