How can I create a two-way mapping in JavaScript, or some other way to swap out values?
data-structures, dictionary, javascript
Solution
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;
}
}
Problem
I currently have a need to temporarily swap out values in a JavaScript string, and therefore I will need to have a two-way map/hash thing. For example, let's say I want to change `\*` to `__asterisk__` (this is just an example, it's not what I'm actually trying to do). I'll have to be able to map `*` to `__asterisk__` (to swap out the value in the original string), but then I'll also have to be able to map `__asterisk__` back to `*` (to get the original string back). Here's some quick pseudo-ish code of the kind of thing that I'm looking for, so you can understand it better: ``` var myString = 'this is \* a test'; // ??? var twoWayMap = new TwoWayMap('*' <---> '__asterisk__', '%' <---> '__percent__', ...); var newString = myString.replace(/\\(.)/g, function(m, c) { return twoWayMap.getKey(c); }); // newString is now 'this is __asterisk__ a test' // ... later in the code ... var oldString = newString.replace(/__([^_]+)__/g, function(m, c) { return twoWayMap.getValue(c); }); // oldString is now 'this is * a test' ``` This is what I've thought about and tried so far: ``` var twoWayMap = {'*': '__asterisk__', '%': '__percent__', ...}; // getKey would be like this: twoWayMap[c]; // getValue would be like: var val; for (var x in twoWayMap) { if (twoWayMap[x] === c) { val = x; break } } ``` The obvious problem with this is that the way to get by value is much too complicated, and I don't want to have to write out the whole thing every single time I have to reverse lookup. I just wanted to know: Is there any way to solve this problem without resorting to looping through an object? If not, is there any way to make it easier or cleaner?