diff options
-rw-r--r-- | js/match.js | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/js/match.js b/js/match.js new file mode 100644 index 0000000..ae13124 --- /dev/null +++ b/js/match.js @@ -0,0 +1,63 @@ +// naive pattern matching +const match = (value, ...patterns) => { + for (let [pattern, action] of patterns) { + if (pattern === value || (typeof pattern === 'function' && pattern(value))) { + return action(value); + } + } + throw new Error("No match found"); +} + + +const isNumber = x => typeof x === 'number'; +const isString = x => typeof x === 'string'; + +const result = match( + 42, + [1, () => "one"], + [2, () => "two"], + [isNumber, x => `number: ${x}`], + [isString, x => `string: ${x}`] +); + +console.log(result); + + + +// slightly fancier pattern matching +const matchObject = (value, ...patterns) => { + for (let [pattern, action] of patterns) { + if (typeof pattern === 'function' && pattern(value)) { + return action(value); + } else if (typeof pattern === 'object' && pattern !== null) { + let isMatch = true; + for (let key in pattern) { + if (pattern[key] !== value[key]) { + isMatch = false; + break; + } + } + if (isMatch) return action(value); + } else if (pattern === value) { + return action(value); + } + } + throw new Error("No match found"); +} + +const isAdult = person => person.age >= 18; +const isChild = person => person.age < 18; + +const personResult = matchObject( + { name: 'Rachel', age: 30 }, + [{ name: 'Rachel', age: 30 }, () => "Rachel, 30 years old"], + [isAdult, person => `${person.name} is an adult`], + [isChild, person => `${person.name} is a child`] +); + +console.log(personResult); + + +// Basic Matching: Checking if a value directly matches a pattern. +// Function Patterns: Uses functions to define more complex matching logic. +// Object Patterns: Match objects based on their properties. \ No newline at end of file |