{"id":13508103,"url":"https://github.com/swannodette/mori","last_synced_at":"2025-05-14T08:06:53.100Z","repository":{"id":3254290,"uuid":"4292299","full_name":"swannodette/mori","owner":"swannodette","description":"ClojureScript's persistent data structures and supporting API from the comfort of vanilla JavaScript","archived":false,"fork":false,"pushed_at":"2020-04-19T19:59:59.000Z","size":1643,"stargazers_count":3381,"open_issues_count":63,"forks_count":146,"subscribers_count":77,"default_branch":"master","last_synced_at":"2025-05-11T03:27:14.942Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://swannodette.github.io/mori","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/swannodette.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-05-11T02:23:01.000Z","updated_at":"2025-05-08T01:22:01.000Z","dependencies_parsed_at":"2022-07-12T15:00:25.367Z","dependency_job_id":null,"html_url":"https://github.com/swannodette/mori","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swannodette%2Fmori","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swannodette%2Fmori/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swannodette%2Fmori/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swannodette%2Fmori/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swannodette","download_url":"https://codeload.github.com/swannodette/mori/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254036812,"owners_count":22003655,"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":[],"created_at":"2024-08-01T02:00:48.033Z","updated_at":"2025-05-14T08:06:53.038Z","avatar_url":"https://github.com/swannodette.png","language":"Clojure","funding_links":[],"categories":["Awesome React","Clojure","Data Structure","Data Structure [🔝](#readme)","数据结构","Libraries"],"sub_categories":["Tools","Runner","运行器","Data Structures","运行器e2e测试"],"readme":"# mori\n\n\u003cimg src=\"http://cloud.github.com/downloads/swannodette/mori/mori.png\" alt=\"Mori\" title=\"Mori\"/\u003e\n\nA simple bridge to ClojureScript's persistent data structures and\n[supporting APIs](http://swannodette.github.io/mori/) for vanilla\nJavaScript. Pull requests welcome.\n\n## Breaking changes in 0.3.0 \n\nThe API now uses idiomatic JavaScript naming conventions.\n\n## Improvements to 0.3.0\n\n### Faster\n\nMori is considerably faster across the board thanks to recent\nenhancements to the ClojureScript compiler. For users who would like\nto benchmark their immutable data structure implementations against\nMori, Mori now exposes direct arity invokes which eliminates previous\ncalling overheads from arity dispatching. See\n[Benchmarking](https://github.com/swannodette/mori/wiki/Benchmarking)\nfor more information.\n\nMori hash maps now default to ClojureScript `ArrayMap`s that are\nautomatically promoted to `PersistentHashMap`s as needed. `ArrayMap`s\ndeliver considerably better performance at small sizes and when simple\nkeys are at play. For example a Mori hash map with less than or equal\nto eight keys can now be built nearly an order of magnitude faster than\nImmutable.js 3.6.2 `Map`s.\n\n### More ES6\n\nAll Mori collections support ES6 iteration via `foo[Symbol.iterator]`\nor `foo[\"@@iterator\"]`.\n\n## Differences from Immutable.js\n\n* A functional API, data structures do not have public methods\n* Faster, ClojureScript data structures have been subjected to more\n  real world usage and continuous benchmarking for nearly 4 years\n* Larger, gzipped the base Mori module is about 6K larger than Immutable.js\n\n## Getting it\n\nYou can install the latest release via npm:\n\n```shell\nnpm install mori\n```\n\nThe installed package contains a single optimized JavaScript file `mori.js`.\n\nLoad `mori` in your Node.js programs as you would any other module:\n\n```javascript\nvar mori = require(\"mori\");\n```\n\nIn a browser, you can load mori with a script tag, as you would any other JavaScript library:\n\n```html\n\u003cscript src=\"mori.js\" type=\"text/javascript\"\u003e\u003c/script\u003e\n```\n\nYou can also load it as an AMD module, e.g. with [RequireJS](http://requirejs.org/).\n\n## Usage\n\nYou can use it from your projects like so:\n\n```javascript\nvar inc = function(n) {\n  return n+1;\n};\n\nmori.intoArray(mori.map(inc, mori.vector(1,2,3,4,5)));\n// =\u003e [2,3,4,5,6]\n```\n\nEfficient non-destructive updates!\n\n```javascript\nvar v1 = mori.vector(1,2,3);\nvar v2 = mori.conj(v1, 4);\nv1.toString(); // =\u003e '[1 2 3]'\nv2.toString(); // =\u003e '[1 2 3 4]'\n```\n\n```javascript\nvar sum = function(a, b) {\n  return a + b;\n};\nmori.reduce(sum, mori.vector(1, 2, 3, 4)); // =\u003e 10\n```\n\nLazy sequences!\n\n```javascript\nvar _ = mori;\n_.intoArray(_.interpose(\"foo\", _.vector(1, 2, 3, 4)));\n// =\u003e [1, \"foo\", 2, \"foo\", 3, \"foo\", 4]\n```\n\nOr if it's more your speed, use it from CoffeeScript!\n\n```coffeescript\ninc = (x) -\u003e x+1  \nr = mori.map inc, mori.vector(1,2,3,4,5)\nmori.intoArray r\n```\n\n### Documentation\n\nYou can find extensive [documentation and examples](http://swannodette.github.io/mori/) here.\n\n## More Examples\n\n### Efficient Freeze/Thaw\n\nFor vectors and maps we provide an efficient thaw and freeze\noperations:\n\n```javascript\nvar m = mori;\n\n// ~220ms with V8 version 3.29.80 MBP 2.26ghz\nfor(var j = 0; j \u003c 10; j++) {\n  var s = new Date();\n  var arr = [];\n  for(var i = 0; i \u003c 10000000; i++) {\n    arr.push(i);\n  }\n  print(\"Array push \" + arr.length + \" items \" + ((new Date())-s));\n  gc();\n}\n\n// ~70ms\nfor(var j = 0; j \u003c 10; j++) {\n  s = new Date();\n  var mv = m._thaw(m.vector());\n  for(var i = 0; i \u003c 10000000; i++) {\n    mv = m._conj.f2(mv, i);\n  }\n  var v = m._freeze(mv);\n  print(\"Mutable vector conj \" + m.count(v) + \" items \" + ((new Date())-s));\n  gc();\n}\n```\n\n### ES6 Map/Set inspired interfaces\n\nAll Mori maps and sets support all the non-mutating methods of the\nproposed ES6\n[Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)\nand\n[Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)\ninterfaces. The main difference with the spec is that key lookup is\nbased on value not reference. `keys`, `values`, and `entries` methods\nreturn the proposed mutable iterators:\n\n```javascript\nvar m = mori;\nvar h = m.hashMap(\"foo\", 1, \"bar\", 2);\n\nh.has(\"foo\"); // =\u003e true\nh.get(\"foo\"); // =\u003e 1\n\nvar iter = h.keys();\niter.next(); // =\u003e {done: false, value: \"foo\"}\n```\n\nThis feature is subject to changes in the ES6 proposal.\n\n### Transducers\n\nMori includes Transducers. Zero allocation collection operations FTW:\n\n```javascript\nvar m = mori;\nvar a = [];\n\nfor(var i = 0; i \u003c 1000000; i++) {\n  a.push(i);\n}\n\n// make it immutable\nvar v = m.into(m.vector(), a);\n\nfunction time(f) {\n  var s = new Date();\n  f();\n  console.log(((new Date())-s)+\"ms\");\n}\n\n// ~190ms V8 version 3.29.80 MBP 2.26ghz\ntime(function() {\n  var xf = m.comp(m.map(m.inc), m.map(m.inc), m.map(m.inc));\n  return m.transduce(xf, m.completing(m.sum), 0, v);\n}, 10);\n\n// ~440ms\ntime(function() {\n  return a.map(m.inc).map(m.inc).map(m.inc).reduce(function(a,b){return a+b;}, 0);\n}, 10);\n```\n\n## Build\n\n### Prerequisites\n\nYou will first need to install the\n[Java](http://www.oracle.com/technetwork/java/javase/downloads/index.html)\nSDK, if it's not already installed on your system.\n\nOn Windows, you will need to manually install\n[Leiningen](http://github.com/technomancy/leiningen). On UNIX-like\nsystems, Leiningen will be installed within the project automatically\nif the `lein` executable is not found on your path or if your `lein`\nversion predates `2.0.0`.\n\n### Clone the repo\n\n```shell\ngit clone https://github.com/swannodette/mori.git\ncd mori\n```\n\n### On a UNIX-like system build with\n\n```shell\n./scripts/build.sh\n```\n\n### Alternatively using npm\n\n```shell\nnpm run-script build\n```\n\n### On Windows\n\n```shell\n./scripts/build.ps1\n```\n\nThe build process will generate an optimized JavaScript file\n`mori.js`, which is suitable for use with Node.js, or in a Web browser\nor other JavaScript environments. You can also load it as an AMD\nmodule.\n\nCopyright (C) 2012-2015 David Nolen and contributors\n\nDistributed under the\n[Eclipse Public License](https://raw.github.com/swannodette/mori/master/epl-v10.html),\nthe same as Clojure.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswannodette%2Fmori","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswannodette%2Fmori","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswannodette%2Fmori/lists"}