{"id":21187554,"url":"https://github.com/pb82/missmatch","last_synced_at":"2026-03-11T06:32:19.680Z","repository":{"id":3864488,"uuid":"4949870","full_name":"pb82/MissMatch","owner":"pb82","description":"Pattern matching for JavaScript inspired by one of the great features of the Haskell language. Suitable for browsers or node.js.","archived":false,"fork":false,"pushed_at":"2018-05-16T22:12:23.000Z","size":164,"stargazers_count":68,"open_issues_count":0,"forks_count":2,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-10T19:24:53.424Z","etag":null,"topics":["javascript","pattern-matching"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pb82.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-07-08T21:03:09.000Z","updated_at":"2024-07-28T08:42:19.000Z","dependencies_parsed_at":"2022-08-31T00:01:12.222Z","dependency_job_id":null,"html_url":"https://github.com/pb82/MissMatch","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pb82%2FMissMatch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pb82%2FMissMatch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pb82%2FMissMatch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pb82%2FMissMatch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pb82","download_url":"https://codeload.github.com/pb82/MissMatch/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225611690,"owners_count":17496510,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","pattern-matching"],"created_at":"2024-11-20T18:37:35.696Z","updated_at":"2026-03-11T06:32:19.641Z","avatar_url":"https://github.com/pb82.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"MissMatch\n=========\n\n[![NPM](https://nodei.co/npm/missmatch.png?compact=true)](https://nodei.co/npm/missmatch/)\n\nPowerful pattern matching for javascript. Can match any kind of javascript value against patterns, bind values and execute handlers when a pattern matches.\n\n- License: MIT\n- Contributions, Issue Reports \u0026 Suggestions welcome!\n\nSimple and concise syntax\n-------------------------\n\n  - 'a' means array\n  - 'o' means object\n  - 'n' means numeric\n  - 's' means string\n  - 'S' means non-blank string\n  - 'b' means boolean\n  - 'f' means function\n  - 'd' means date\n  - 'r' means regular expression\n  - '|' means the rest of a list\n  - '_' means wildcard (match anything)\n\n\nBasic usage\n-----------\n\n```\nmm.match(\u003cOBJECT\u003e, {   \n  \u003cPATTERN\u003e: \u003cHANDLER\u003e,\n  ...\n}, \u003cOPTIONS\u003e);\n\n```\n\nor (alternatively since 0.1.2)\n\n```\nmm.match(\u003cOBJECT\u003e, [   \n  \u003cPATTERN\u003e, \u003cHANDLER\u003e,\n  ...\n], \u003cOPTIONS\u003e);\n```\n\n(the second approach has the advantage that patterns can be stored in variables)\n\nOptions are, well, optional. If provided they must be in the form of an object. The only supported option at the moment is `arrow`. If set to true bound parameters will be passed as arguments to handler functions instead of injected into their `this` context.\nThis is required to support arrow functions because they do not have their own `this` context (or rather `this` inside an arrow function refers to the surrounding context).\n\nNested patterns\n---------------\n\nPatterns may be arbitrarily nested.\n\n  - a(n, n) matches an array with exactly two numbers (e.g. [1,2]).  \n  \n  - a(a, a(n)) matches an array that is composed of two nested arrays. The second array is required to contain exactly one number.  \n  \n  - a(a, o(.x, .y)) matches an array that is composed of an array and then an object. The object is required to contain at least \n    the two properties 'x' and 'y'.  \n\n\nBinding values\n--------------\n\n  - a(n@x, n@y) matches an array that is composed of exactly two numbers where the first one is bound to the variable 'x' and the second one\n    to 'y'. They can be used in the handler function of the pattern:  \n    \n```  js\nmm.match([2,3], {   \n'a(n@x, n@y)': function () { return this.x * this.y; },\n'_': function () { /* Match all */ }\n});\n\n```\n\nReturning values from a (matching) pattern\n------------------------------------------\n\nThe right side of a pattern may be a function or any other value. If it is a function and the pattern matches, then the result of the function is returned.\nIf it is a non-function value and the pattern matches, then this value is returned. In earlier version (pre 0.1.0) only handler functions were allowed.\n\n```  js\n// Handler function\nmm.match(42, {   \n'n@x': function () { return this.x; }\n});\n\n// Return a value when the pattern matches\nmm.match(42, {   \n'n': 42\n});\n\n```\n\nUsing arrow functions as handlers\n---------------------------------\n\nStarting with version 1.0.0 you can use ES6 arrow functions as handlers provided you set the `arrow: true` option:\n\n```js\nmm.match({x: 5, y: 6}, {\n'o(.x@left, .y@right)': ({left, right}) =\u003e left * right\n}, {arrow: true});\n```\n\nWhen using arrow functions, bound parameters will be passed as arguments to them.\n\nMatching objects\n----------------\n\n  - o matches any object.\n\n  - o(.x) matches an object that is required to have a property namend 'x' which must belong to the object itself and must not be a part\n    of the prototype chain.\n    \n  - o(:x) matches an object that is required to have a property named 'x' which may also be part of the prototype chain.\n  \n  - o(:x, .y) matches an object that is required to have (at least) two properties 'x' and 'y'. 'y' is required to belong to the object itself\n    while 'x' may be part of the prototype cain.\n\nMatching object properties by type\n----------------------------------\n\n  - o(.x:n) matches an object with at least a property 'x' which is required to be a number. You can also bind the number's value:  \n    \n      * o(.x:n@x)  \n      \n  - o(.coord:o(.x:n@x, .y:n@y)) matches an object that has (at least) a property 'coord'. 'coord' is further required to be an object and provide\n    (at least) the properties 'x' and 'y'. They are then bound to variables and can be used in the handler function.  \n    \n\nLiterals\n--------\n\n  Literals can be matched for strings, numbers, booleans and dates. Literals may also be bound to names.\n  \n  - n(121.5) denotes the numeric literal 121.5.\n    \n  - s(\"a_str\") denotes the string literal 'a_str'.\n  \n  - s(/^a*/) requires the string to match the regular expression /^a*/.\n  \n  - b(true) denotes a boolean literal that only matches 'true' values.\n  \n  - d(\"2012/2/28\") denotes the date literal '2012/2/28'. Every valid JavaScript date string is accepted in the pattern. Time information may also be specified: d(\"2012/03/01 02:03:45\")\n  \n\nLiteral lists\n-------------\n  \n  - n(1,2,3) matches if one of the numbers 1, 2 or 3 occurs.\n  \n  - s(\"a\", \"b\") matches if a string \"a\" or a string \"b\" occurs.\n  \n  - n(1,2,3)@x matches if one of the numbers 1, 2 or 3 occurs and binds the actual value to the variable 'x'.\n  \n  - d(\"2012/2/28\", \"2012/3/01\") matches if one of the specified dates occur.\n      \n      \nThe rest of an array\n--------------------\n\n  - a(n,n,n|) matches an array that is required to contain at least three numeric values, but may also contain more.  \n    \n  - a(n,n,n|@r) matches the same array, but binds the rest (everything but the first three items) to the variable 'r'.\n  \nNote that the rest of an array (if there is a rest left to be matched) will always be an array itself even if there is only one item left\nto match the rest to.\n\n\nMatching the arguments of the enclosing function\n------------------------------------------------\n\nYou can match against the calling function's arguments without passing the arguments object. It's a nice way to write dispatching or generic functions.\n(deprecated as of 0.1.0)\n\n```  js\nfunction plus() {\n  mm.matchArgs({\n    // Function arguments are treated like arrays.\n    // If we pass in two numbers, we ADD them:\n    'a(n@a,n@b)': function () { return this.a + this.b; },\n    \n    // If we pass in two booleans we AND them:\n    'a(b@a,b@b)': function () { return this.a \u0026\u0026 this.b; }    \n  });\n}\n\nplus(2,4);          // 6 \nplus(true, false);  // false\n```\n\nAPI\n===\n\nThe API consists of four functions:\n  \n  - **match** takes a value to match and a JavaScript Object containing the patterns and handlers. If one of the patterns matches, then\n    it's handler function is executed.\n    \n  - **matchJSON** is equivalent to match(JSON.parse(obj_to_match), {...})\n  \n  - **matchArgs** lets you match against the calling function's arguments. You don't have to pass the arguments object, only the patterns.\n    Function arguments are matched like arrays.\n  \n  - **compile** compiles a single pattern (string) to a function. The function can be executed on some input value and will return an object\n    with the properties 'result' and 'context'. If the pattern matched the input, 'result' will be true and 'context' will be an object containing\n    all bindings.\n\n\nInstallation\n============\n\nMissMatch can be used in the Browser, with Node.js and possibly with other server-side JavaScript Engines like Rhino (haven't tested that yet).\nIt has no dependencies.\n\nBrowser\n-------\n```\n\u003cscript type=\"text/javascript\" src=\"/path/to/MissMatch.js\"\u003e\u003c/script\u003e\n```\n\nThe functions 'match', 'matchJSON', ',matchArgs' and 'compile' are all bound to an object with the name 'mm'.\n\nNode.js\n-------\n\n  - npm install missmatch\n  - (optional) npm test missmatch\n\nVersion History\n---------------\n  - 1.0.1\n    * Add Typescript typings\n    * bugfix: version was not exported\n\n  - 1.0.0\n    * `matchArgs` has been removed\n    * Options can be passed into `match` as a third argument\n    * Support for arrow function via the `arrow: true` option\n\n  - 0.1.4\n    * bugfix: accidentally added grunt-cli to dependencies instead of dev-dependencies\n\n  - 0.1.3\n    * bugfix: rest parameter didn't match if there wasn't a rest\n\n  - 0.1.2\n    * patterns and handlers can be contained in an array\n    * includes minified library\n    * added gruntfile\n    * available on bower\n\n  - 0.1.1\n    * can match non-blank strings (with S)\n\n  - 0.1.0\n    * Non-function handler arguments allowed\n    * matchArgs is now deprecated\n\n  - 0.0.5 (Bugfix release)\n    * capital 'E' accepted in numeric expressions (e.g. 3E-5)\n    * code revised\n\n  - 0.0.4:\n    * can match strings with regular expressions (e.g. s(/^a*/, /[0-9]*/)).\n    * can match regular expression objects.\n    * code revised.\n\n  - 0.0.3:\n    * improved performance.\n    * can match function arguments nicely (matchArgs).\n    * can match date objects.\n    * version string added (mm.version).\n\n  - 0.0.2: \n    * Can match properties in the prototype chain (with ':' instead of '.').\n    * Better support for valid variable and property names ($, _ and numbers allowed).\n    * Will throw an exception if the same name is bound multiple times. In 0.0.1 The value was silently overwritten.\n    * Improved parser error messages.\n    \n  - 0.0.1: Initial Release.  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpb82%2Fmissmatch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpb82%2Fmissmatch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpb82%2Fmissmatch/lists"}