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?
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;
}
}