Skip to content

Instantly share code, notes, and snippets.

@acro5piano
Last active March 27, 2020 13:14
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 acro5piano/5f6221f7ac2c3f692425e9627acd82dd to your computer and use it in GitHub Desktop.
Save acro5piano/5f6221f7ac2c3f692425e9627acd82dd to your computer and use it in GitHub Desktop.
pattern match in js
// https://elixir-lang.org/getting-started/case-cond-and-if.html#case
function elixir(...conds) {
function arrayEqualsCond(a, b) {
if (a.length !== b.length) {
return false;
}
let eq = true;
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i] && !(b[i] instanceof Matcher)) {
eq = false;
}
}
return eq;
}
class Matcher {
constructor(conds) {
this.conds = conds;
}
when(...exp) {
return {
then: value => {
// console.log(this.conds, exp);
if (arrayEqualsCond(this.conds, exp)) {
this.value = value;
}
}
};
}
else(value) {
if (this.value === undefined) {
this.value = value;
}
}
}
class ElixirCase {
constructor(conds) {
this.conds = conds;
}
do(callback) {
const matcher = new Matcher(this.conds);
callback(matcher);
return matcher.value;
}
}
return new ElixirCase(conds);
}
const res = elixir(1, 2, 4).do(_ => {
_.when(4, 5, 6).then("This clause won't match");
_.when(1, _, 3).then("This clause will match and binded to _.value");
_.else("Nothing hit");
});
console.log(res); // => "This clause will match and binded to _.value"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment