Skip to content

Instantly share code, notes, and snippets.

@momocow
Last active January 9, 2020 12:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save momocow/ee03d5241593e19129d7bce27dadd21a to your computer and use it in GitHub Desktop.
Save momocow/ee03d5241593e19129d7bce27dadd21a to your computer and use it in GitHub Desktop.
Extremely dead simple bidirectional JS objects mimic native objects based on ES6 Proxy.
export const INVERSE = Symbol('inverse')
export function bimap (obj = {}) {
const inverse = Object.entries(obj)
.reduce(
(o, [k, v]) =>
Object.assign(o, { [v]: k }),
{}
)
return new Proxy(obj, {
get (target, prop) {
return prop === INVERSE ? inverse
: prop in target ? target[prop]
: inverse[prop]
},
set (target, prop, value) {
target[prop] = value
inverse[value] = prop
return true
},
has (target, prop) {
return prop === INVERSE ||
prop in target ||
prop in inverse
},
deleteProperty (target, prop) {
if (prop in target) {
delete inverse[target[prop]]
delete target[prop]
return true
} else if (prop in inverse) {
delete target[inverse[prop]]
delete inverse[prop]
return true
}
return false
}
})
}
@momocow
Copy link
Author

momocow commented Jan 9, 2020

Keys and values must be unique pairs, i.e. must not overlap.

The inverse object is pre-built once constructed.

const o = bimap({a:'va', b:'vb', c:'vc'})
console.log(o.a) // "va"
console.log(o.b) // "vb"
console.log(o.c) // "vc"
console.log(o.va) // "a"
console.log(o.vb) // "b"
console.log(o.vc) // "c"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment