mori
Version:
Persistent Data Structures for JavaScript
1,622 lines (1,443 loc) • 59.5 kB
HTML
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>mori</title>
<link href="http://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="css/base.css" />
<link rel="stylesheet" type="text/css" href="css/shCore.css" />
<link rel="stylesheet" type="text/css" href="css/shThemeMarginalia.css" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="js/xregexp-min.js"></script>
<script type="text/javascript" src="js/shCore.js"></script>
<script type="text/javascript" src="js/shBrushClojure.js"></script>
<script type="text/javascript" src="js/shBrushJScript.js"></script>
<script type="text/javascript" src="http://use.typekit.com/rvk4jgw.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/mori/0.2.9/mori.js"></script>
</head>
<body>
<div class="wrapper">
<div class="mori-nav">
<ul>
<li class="main">
<a href="#title" class="toc-title">Mori</a>
<ul>
<li><a href="https://github.com/swannodette/mori"> Github Repository</a></li>
</ul>
</li>
<li>
<a href="#rationale" class="toc-title">Rationale</a>
<ul>
<li><a href="#immutability"> Immutability</a></li>
<li><a href="#island"> Mori is not an island</a></li>
<li><a href="#usage"> Using Mori</a></li>
<li><a href="#notation"> Notation</a></li>
</ul>
</li>
<li>
<a href="#fundamentals" class="toc-title">Fundamentals</a>
<ul>
<li><a href="#equals"> equals</a></li>
<li><a href="#hash"> hash</a></li>
</ul>
</li>
<li>
<a href="#predicates" class="toc-title">Type Predicates</a>
<ul>
<li><a href="#isList">isList</a></li>
<li><a href="#isSeq">isSeq</a></li>
<li><a href="#isVector">isVector</a></li>
<li><a href="#isMap">isMap</a></li>
<li><a href="#isSet">isSet</a></li>
<li><a href="#isCollection">isCollection</a></li>
<li><a href="#isSequential">isSequential</a></li>
<li><a href="#isAssociative">isAssociative</a></li>
<li><a href="#isCounted">isCounted</a></li>
<li><a href="#isIndexed">isIndexed</a></li>
<li><a href="#isReduceable">isReduceable</a></li>
<li><a href="#isSeqable">isSeqable</a></li>
<li><a href="#isReversible">isReversible</a></li>
</ul>
</li>
<li>
<a href="#collections" class="toc-title">Collections</a>
<ul>
<li><a href="#list"> list</a></li>
<li><a href="#vector"> vector</a></li>
<li><a href="#hashMap"> hashMap</a></li>
<li><a href="#set"> set</a></li>
<li><a href="#sortedSet"> sortedSet</a></li>
<li><a href="#range"> range</a></li>
<li><a href="#queue"> queue</a></li>
</ul>
</li>
<li>
<a href="#collection_operations" class="toc-title">Collection Operations</a>
<ul>
<li><a href="#conj"> conj</a></li>
<li><a href="#into"> into</a></li>
<li><a href="#assoc"> assoc</a></li>
<li><a href="#dissoc"> dissoc</a></li>
<li><a href="#distinct"> distinct</a></li>
<li><a href="#empty"> empty</a></li>
<li><a href="#get"> get</a></li>
<li><a href="#getIn"> getIn</a></li>
<li><a href="#hasKey"> hasKey</a></li>
<li><a href="#find"> find</a></li>
<li><a href="#nth"> nth</a></li>
<li><a href="#last"> last</a></li>
<li><a href="#assocIn"> assocIn</a></li>
<li><a href="#updateIn"> updateIn</a></li>
<li><a href="#count"> count</a></li>
<li><a href="#isEmpty"> isEmpty</a></li>
<li><a href="#peek"> peek</a></li>
<li><a href="#pop"> pop</a></li>
<li><a href="#zipmap"> zipmap</a></li>
<li><a href="#reverse"> reverse</a></li>
</ul>
</li>
<li>
<a href="#vector_operations" class="toc-title">Vector Operations</a>
<ul>
<li><a href="#subvec"> subvec</a></li>
</ul>
</li>
<li>
<a href="#hashMap_operations" class="toc-title">Hash Map Operations</a>
<ul>
<li><a href="#keys"> keys</a></li>
<li><a href="#vals"> vals</a></li>
<li><a href="#merge"> merge</a></li>
</ul>
</li>
<li>
<a href="#set_operations" class="toc-title">Set Operations</a>
<ul>
<li><a href="#disj"> disj</a></li>
<li><a href="#union"> union</a></li>
<li><a href="#intersection"> intersection</a></li>
<li><a href="#difference"> difference</a></li>
<li><a href="#isSubset"> isSubset</a></li>
<li><a href="#isSuperset"> isSuperset</a></li>
</ul>
</li>
<li>
<a href="#sequences" class="toc-title">Sequences</a>
<ul>
<li><a href="#first"> first</a></li>
<li><a href="#rest"> rest</a></li>
<li><a href="#seq"> seq</a></li>
<li><a href="#cons"> cons</a></li>
<li><a href="#concat"> concat</a></li>
<li><a href="#flatten"> flatten</a></li>
<li><a href="#intoArray"> intoArray</a></li>
<li><a href="#each"> each</a></li>
<li><a href="#map"> map</a></li>
<li><a href="#mapcat"> mapcat</a></li>
<li><a href="#filter"> filter</a></li>
<li><a href="#remove"> remove</a></li>
<li><a href="#reduce"> reduce</a></li>
<li><a href="#reduceKV"> reduceKV</a></li>
<li><a href="#take"> take</a></li>
<li><a href="#takeWhile"> takeWhile</a></li>
<li><a href="#drop"> drop</a></li>
<li><a href="#dropWhile"> dropWhile</a></li>
<li><a href="#some"> some</a></li>
<li><a href="#every"> every</a></li>
<li><a href="#sort"> sort</a></li>
<li><a href="#sortBy"> sortBy</a></li>
<li><a href="#interpose"> interpose</a></li>
<li><a href="#interleave"> interleave</a></li>
<li><a href="#iterate"> iterate</a></li>
<li><a href="#repeat"> repeat</a></li>
<li><a href="#repeatedly"> repeatedly</a></li>
<li><a href="#partition"> partition</a></li>
<li><a href="#partitionBy"> partitionBy</a></li>
<li><a href="#groupBy"> groupBy</a></li>
</ul>
</li>
<li>
<a href="#helpers" class="toc-title">Helpers</a>
<ul>
<li><a href="#primSeq"> primSeq</a></li>
<li><a href="#identity"> identity</a></li>
<li><a href="#constantly"> constantly</a></li>
<li><a href="#inc"> inc</a></li>
<li><a href="#dec"> dec</a></li>
<li><a href="#sum"> sum</a></li>
<li><a href="#isEven"> isEven</a></li>
<li><a href="#isOdd"> isOdd</a></li>
<li><a href="#comp"> comp</a></li>
<li><a href="#juxt"> juxt</a></li>
<li><a href="#knit"> knit</a></li>
<li><a href="#pipeline"> pipeline</a></li>
<li><a href="#partial"> partial</a></li>
<li><a href="#curry"> curry</a></li>
<li><a href="#curry"> fnil</a></li>
<li><a href="#toClj"> toClj</a></li>
<li><a href="#toJs"> toJs</a></li>
</ul>
</li>
</ul>
</div>
<div class="mori-content">
<main>
<h1 id="title" class="tk-anisette-petite">mori</h1>
<p>
A library for using ClojureScript's persistent data
structures and supporting API from the comfort of
vanilla JavaScript.
</p>
<h2 id="rationale">Rationale</h2>
<p>
JavaScript is a powerful and flexible dynamic
programming language with a beautiful simple
associative model at its core. However this design
comes at the cost of ubiquitous mutability. Mori
embraces the simple associative model but leaves
mutability behind. Mori delivers the following
benefits to JavaScript:
</p>
<ul>
<li>Efficient immutable data structures - no cloning required</li>
<li>Uniform iteration for all types</li>
<li>Value based equality</li>
</ul>
<p>
Modern JavaScript engines like V8, JavaScriptCore, and
SpiderMonkey deliver the performance needed to implement
persistent data structures well.
</p>
<h3 id="immutability">Immutability</h3>
<p>
Mori delivers highly tuned persistent data structures
based on the ones provided in Clojure. When using
Mori data structures and operations you do not need to
defensively clone as you often do in JavaScript.
By providing immutable data structures, Mori encourages
value oriented programming.
</p>
<h3 id="island">Mori is not an island</h3>
<p>
Beyond the the core philosophy Mori makes no other
assumptions about how you might use it. In fact, Mori
has changed some aspects of the ClojureScript API in
order to better accomodate usage from JavaScript and
languages that target JavaScript like
CoffeeScript. For example, where it makes sense, Mori
returns regular JavaScript arrays so that you can use
destructuring syntax where available.
The following example is in CoffeeScript:
</p>
<div class="example">
<pre class="brush: javascript">
m = mori;
[a, b] = m.juxt(m.inc, m.dec)(1); // a = 2, b = 0
</pre>
</div>
<h3 id="usage">Using Mori</h3>
<p>
Mori can be used in precisely the same way that
libraries like Underscore.js are used. Mori of course
provides not only the same functionality but it
delivers a rich set of data structures.
Mori's operators are more general than the ones
provided by Underscore.js - they work on nearly all
the native JavaScript types. In those cases where they
do not work you usually just need to wrap the type
in <code>mori.primSeq(...)</code>.
</p>
<h3 id="notation">Notation</h3>
<p>
Each entry is annotated with the signature with an
accompanying description and some relevant
examples. Optional parameters appear
as <code>[option]</code> in the signature. Sometimes
the signature or description will mention <b>coll</b>
for collection. In general collections can be
converted in to sequences for manipulation via the
various sequence operations. This include all Mori
collections as well as JavaScript Arrays and Strings.
</p>
<p>
All the examples are in JavaScript or CoffeeScript. However,
for simplicity's sake we show the <i>results</i> of operations
in Clojure literal syntax notation.
</p>
<div class="example">
<pre class="brush: clojure">
(1 2 3 4) ;; list
[1 2 3 4] ;; vector
{"foo" 1, "bar" 2} ;; hash map / sorted-map
#{"cat" "bird" "dog"} ;; set / sorted-set
</pre>
</div>
<h2 id="fundamentals">Fundamentals</h2>
<h3 id="equals">
equals
<span class="sig">mori.equals(x, y)</span>
</h3>
<p>
Test whether two values are equal. Works on all Mori collections.
Note that two seqable values will be tested on deep equality of their
contents.
</p>
<div class="example">
<pre class="brush: javascript">
var l0 = mori.list(1,2,3);
var l1 = mori.list(1,2,3);
mori.equals(l0, l1); // => true
var v = mori.vector(1,2,3);
mori.equals(v, l0); // => true
var m0 = mori.toClj({foo: 1});
var m1 = mori.toClj({foo: 1});
mori.equals(m0, m1); // => true
</pre>
</div>
<h3 id="hash">
hash
<span class="sig">mori.hash(x)</span>
</h3>
<p>
Returns the hash code for a value. Values for
which <code>mori.equals</code> returns true have identical
hash codes.
</p>
<div class="example">
<pre class="brush: javascript">
var l = mori.list(1, 2, 3);
var v = mori.vector(1, 2, 3);
mori.hash(l) == mori.hash(v); // => true
</pre>
</div>
<h2 id="predicates">Type Predicates</h2>
<h3 id="isList">
isList
<span class="sig">mori.isList(coll)</span>
</h3>
<p>
Test if something is a list-like collection. Lists support efficient adding to the head.
</p>
<h3 id="isSeq">
isSeq
<span class="sig">mori.isSeq(coll)</span>
</h3>
<p>Test if something is a sequence (i.e. iterable)</p>
<h3 id="isVector">
isVector
<span class="sig">mori.isVector(coll)</span>
</h3>
<p>
Test if something is a vector-like collection. Vectors support random access. It is efficient
to add to the end of a vector.
</p>
<h3 id="isMap">
isMap
<span class="sig">mori.isMap(coll)</span>
</h3>
<p>
Test if something is a map-like collection. Maps support random access and arbitrary keys.
</p>
<h3 id="isSet">
isSet
<span class="sig">mori.isSet(coll)</span>
</h3>
<p>
Test if something is a hash set.
</p>
<h3 id="isCollection">
isCollection
<span class="sig">mori.isCollection(coll)</span>
</h3>
<p>Test if something is a collection - lists, maps, sets, vectors are all collections.</p>
<h3 id="isSequential">
isSequential
<span class="sig">mori.isSequential(coll)</span>
</h3>
<p>
Test if something is sequential. For example vectors are sequential but are not sequences.
They can however be converted into something iterable by calling seq on them.
</p>
<h3 id="isAssociative">
isAssociative
<span class="sig">mori.isAssociative(coll)</span>
</h3>
<p>
Test if something is associative - i.e. vectors and maps.
</p>
<h3 id="isCounted">
isCounted
<span class="sig">mori.isCounted(coll)</span>
</h3>
<p>
Test if something can give its count in O(1) time.
</p>
<h3 id="isIndexed">
isIndexed
<span class="sig">mori.isIndexed(coll)</span>
</h3>
<p>
Test if something is indexed - i.e. vectors.
</p>
<h3 id="isReduceable">
isReduceable
<span class="sig">mori.isReduceable(coll)</span>
</h3>
<p>
Test if something is reduceable.
</p>
<h3 id="isSeqable">
isSeqable
<span class="sig">mori.isSeqable(coll)</span>
</h3>
<p>
Test if something can be coerced into something iterable.
</p>
<h3 id="isReversible">
isReversible
<span class="sig">mori.isReversible(coll)</span>
</h3>
<p>
Test if something can be reversed in O(1) time.
</p>
<h2 id="collections">Collections</h2>
<h3 id="list">
list
<span class="sig">mori.list(arg0, arg1, ...)</span>
</h3>
<p>
Constructs an immutable list. Lists support efficient
addition at the head of the list. It's important to
remember that the cost of operations like
<code>mori.nth</code> will be linear in the size of
the list.
</p>
<div class="example">
<pre class="brush: javascript">
var l = mori.list(2,3);
mori.cons(1, l); // => (1 2 3)
</pre>
</div>
<h3 id="vector">
vector
<span class="sig">mori.vector(arg0, arg1, ...)</span>
</h3>
<p>
Constructs an immutable vector. Vectors support efficient
addition at the end. They also support efficient random
access. You will probably use <code>mori.vector</code> much
more often than <code>mori.list</code>
</p>
<div class="example">
<pre class="brush: javascript">
var v = mori.vector(1,2,3,4);
mori.nth(v, 0); // => 1
</pre>
</div>
<h3 id="hashMap">
hashMap
<span class="sig">mori.hashMap(key0, val0, key1, val1, ...)</span>
</h3>
<p>
Constructs an immutable hash map. Unlike JavaScript
objects Mori PersistentHashMap support complex
keys. It's recommended that you only use immutable
values for your keys - numbers, strings or a Mori
collection.
</p>
<div class="example">
<pre class="brush: javascript">
var m0 = mori.hashMap("foo", 1, "bar", 2);
// m0 = {"foo" 1, "bar" 2}
mori.get(m0, "bar"); // => 2
var m1 = mori.assoc(m0, m.vector(1,2), 3);
// m1 = {"foo" 1, "bar" 2, [1 2] 3}
mori.get(m1, m.vector(1,2)); // => 3
</pre>
</div>
<h3 id="sorted_map">
sorted_map
<span class="sig">mori.sorted_map(key0, val0, key1, val1, ...)</span>
</h3>
<p>
Like a hash map but keeps its keys ordered.
</p>
<div class="example">
<pre class="brush: clojure">
mori.sorted_map(2, "two", 3, "three", 1, "one"); // {1 "one", 2 "two", 3 "three"}
</pre>
</div>
<h3 id="set">
set
<span class="sig">mori.set(seqable)</span>
</h3>
<p>
Constructs a collection of unique items. You may pass
in any seqable type - this includes JavaScript arrays
and strings. There are several operations unique to
sets which do not apply to the other collections.
</p>
<div class="example">
<pre class="brush: clojure">
var s = mori.set(["bird", "cat", "dog"]);
mori.conj(s, "dog"); // => #{"bird" "cat" "dog"}
mori.conj(s, "zebra"); // => #{"bird" "cat" "dog" "zebra"}
</pre>
</div>
<h3 id="sortedSet">
sortedSet
<span class="sig">mori.sortedSet(arg0, arg1, ...)</span>
</h3>
<p>
Like set but keeps its elements ordered.
</p>
<div class="example">
<pre class="brush: clojure">
mori.sortedSet(3,2,1,3); // #{1 2 3}
</pre>
</div>
<h3 id="range">
range
<span class="sig">mori.range([start], [end], [step])</span>
</h3>
<p>
Construct a potentially infinite lazy range of values.
</p>
<p>
With no parameters, a infinite lazy sequence starting
at 0 will be returned.
</p>
<div class="example">
<pre class="brush: javascript">
var r = mori.range(); // => (0 1 2 3 …)
</pre>
</div>
<p>
A single parameter serves as the <code>end</code>
(exclusive) argument.
</p>
<div class="example">
<pre class="brush: clojure">
var r = mori.range(10); // => (0 1 2 3 4 5 6 7 8 9)
</pre>
</div>
<p>
Two parameters serve as <code>start</code> and
<code>end</code>.
</p>
<div class="example">
<pre class="brush: clojure">
var r = mori.range(1,5); // => (1 2 3 4)
</pre>
</div>
<p>
If three parameters are specified, the third serves
as a <code>step</code> argument.
</p>
<div class="example">
<pre class="brush: clojure">
var r = mori.range(1,9,2); // => (1 3 5 7)
</pre>
</div>
<h3 id="queue">
queue
<span class="sig">mori.queue(arg0, arg1, ...)</span>
</h3>
<p>
Constructs a persistent queue. Queues support efficient
addition at the end and removal from the front.
</p>
<div class="example">
<pre class="brush: clojure">
var q0 = mori.queue(1, 2); // => #queue [1 2]
var q1 = mori.conj(q0, 3); // => #queue [1 2 3]
mori.peek(q1); // => 1
mori.pop(q1); // => #queue [2 3]
mori.rest(q1); // => (2 3)
</pre>
</div>
<h2 id="collection_operations">Collection Operations</h2>
<h3 id="conj">
conj
<span class="sig">mori.conj(coll, arg0, arg1, ...)</span>
</h3>
<p>
Add something to a collection. The behavior depends on
the type of the collection.
</p>
<div class="example">
<pre class="brush: javascript">
var l = mori.list(2,3);
mori.conj(l, 1); // => (1 2 3)
var v = mori.vector(1,2);
mori.conj(v, 3); // => [1 2 3]
var m = mori.hashMap("foo", 1);
mori.conj(m, mori.vector("bar", 2));; // => {"foo" 1 "bar" 2}
var s = mori.set(["cat", "bird", "dog"]);
mori.conj(s, "zebra"); // => #{"cat" "bird" "dog" "zebra"}
</pre>
</div>
<h3 id="into">
into
<span class="sig">mori.into(coll, from)</span>
</h3>
<p>
Add all the items in the second collection to the first one as
if calling <code>mori.conj</code> repeatedly.
</p>
<div class="example">
<pre class="brush: javascript">
var l = mori.list(2,3);
var v = mori.vector(1,2);
mori.into(l, v); // => (2 1 2 3)
mori.into(l, l); // => (3 2 2 3)
mori.into(v, l); // => [1 2 2 3]
mori.into(v, v); // => [1 2 1 2]
</pre>
</div>
<h3 id="assoc">
assoc
<span class="sig">mori.assoc(coll, key0, val0, key1, val1, ...)</span>
</h3>
<p>
Associate a new key-value pair in an associative collection. Works
on vectors and maps.
</p>
<div class="example">
<pre class="brush: javascript">
var v = mori.vector("foo", "bar", "baz");
mori.assoc(v, 1, "quux"); // => ["foo" "quux" "baz"]
var m = mori.hashMap("foo", 1);
mori.assoc(m, "bar", 2); // => {"foo" 1 "bar" 2}
mori.assoc(m, "foo", 6); // => {"foo" 6}
</pre>
</div>
<h3 id="dissoc">
dissoc
<span class="sig">mori.dissoc(coll, key0, key1, ...)</span>
</h3>
<p>
Removes keys from an associative collection. Works on maps.
</p>
<div class="example">
<pre class="brush: javascript">
var m = mori.hashMap("foo", 1, "bar", 2, "baz", 3);
mori.dissoc(m, "bar", "baz"); // => {"foo" 1}
</pre>
</div>
<h3 id="distinct">
distinct
<span class="sig">mori.distinct(coll)</span>
</h3>
<p>
Returns a sequence of the elements of coll with duplicates removed.
</p>
<div class="example">
<pre class="brush: javascript">
var v = mori.vector(1, 1, 2, 3, 3, 4, 5);
mori.distinct(v); // => (1 2 3 4 5)
</pre>
</div>
<h3 id="empty">
empty
<span class="sig">mori.empty(coll)</span>
</h3>
<p>
Remove everything from a collection.
</p>
<div class="example">
<pre class="brush: javascript">
var m = mori.hashMap("foo", 1, "bar", 2, "baz", 3);
mori.empty(m); // => {}
var v = mori.vector("foo", "bar", "baz");
mori.empty(v); // => []
</pre>
</div>
<h3 id="get">
get
<span class="sig">mori.get(coll, key, [not-found])</span>
</h3>
<p>Retrieve a value from a collection.</p>
<div class="example">
<pre class="brush: javascript">
var v = mori.vector("foo", "bar", "baz");
mori.get(v, 1); // "bar"
var m = mori.hashMap("foo", 1, "bar", 2);
mori.get(m, "foo"); // => 1
mori.get(m, "baz", "nope"); // => "nope"
</pre>
</div>
<h3 id="getIn">
getIn
<span class="sig">mori.getIn(coll, keys, [not-found])</span>
</h3>
<p>
Retrieve a value from a nested collection. <code>keys</code> may be any seqable object.
</p>
<div class="example">
<pre class="brush: javascript">
var v = mori.vector("foo", "bar", "baz");
var v2 = mori.vector("quux", v);
mori.getIn(v2, [1, 2]); // => "baz"
var m = mori.hashMap("foo", 1, "bar", 2);
var m2 = mori.hashMap("baz", 3, "quux", m);
mori.getIn(m2, ["quux", "bar"]); // => 2
</pre>
</div>
<h3 id="hasKey">
hasKey
<span class="sig">mori.hasKey(coll, key)</span>
</h3>
<p> Returns true if the collection has the given key/index. Otherwise, returns false.</p>
<div class="example">
<pre class="brush: javascript">
var v = mori.vector("foo", "bar", "baz");
mori.hasKey(v, 1); // => true
mori.hasKey(v, 9); // => false
var m = mori.hashMap("foo", 1, "bar", 2);
mori.hasKey(m, "foo"); // => true
mori.hasKey(m, "quux"); // => false
var s = mori.set(["foo", "bar", "baz"]);
mori.hasKey(s, "foo"); // => true
mori.hasKey(s, "quux"); // => false
</pre>
</div>
<h3 id="find">
find
<span class="sig">mori.find(coll, key)</span>
</h3>
<p>
Returns the key value pair as an array for a given key. Returns null if that key isn't present.
</p>
<div class="example">
<pre class="brush: javascript">
var v = mori.vector("foo", "bar", "baz")
mori.find(v, 2) // => [2, "baz"]
mori.find(v, 9) // null
var m = mori.hashMap("foo", 1, "bar", 2)
mori.find(m, "foo") // => ["foo", 1]
mori.find(m, "quux") // null
</pre>
</div>
<h3 id="nth">
nth
<span class="sig">mori.nth(coll, index)</span>
</h3>
<p>
Get the value at the specified index. Complexity
depends on the collection. <code>nth</code> is essentially
constant on vector, but linear on lists. For collections
which are not sequential like sets and hash-map, the
collection will be coerced into a sequence first.
</p>
<div class="example">
<pre class="brush: javascript">
var v = mori.vector("foo", "bar", "baz");
mori.nth(v, 1); // => "bar"
</pre>
</div>
<h3 id="last">
last
<span class="sig">mori.last(coll)</span>
</h3>
<p>
Get the last value in a collection, in linear time.
</p>
<div class="example">
<pre class="brush: javascript">
var v = mori.vector("foo", "bar", "baz");
mori.last(v); // => "baz"
</pre>
</div>
<h3 id="assocIn">
assocIn
<span class="sig">mori.assocIn(coll, keys, val)</span>
</h3>
<p>
Convenience function for assoc'ing nested associative
data structures. <code>keys</code> may be any seqable.
</p>
<div class="example">
<pre class="brush: javascript">
var h = mori.hashMap("foo", mori.hashMap("bar", 1));
mori.assocIn(h, ["foo", "baz"], 2); // => {"foo" {"bar" 1, "baz" 2}}
</pre>
</div>
<h3 id="updateIn">
updateIn
<span class="sig">mori.updateIn(coll, keys, function)</span>
</h3>
<div class="example">
<pre class="brush: javascript">
var h = mori.hashMap("foo", mori.vector(1, 2, 3));
mori.updateIn(h, ["foo", 1], mori.inc); // => {"foo" [1 3 3]}
</pre>
</div>
<h3 id="count">
count
<span class="sig">mori.count(coll)</span>
</h3>
<p> Returns the length of the collection.</p>
<div class="example">
<pre class="brush: javascript">
var l = mori.list("foo", "bar", "baz");
mori.count(l) // 3
var v = mori.vector("foo", "bar", "baz");
mori.count(v) // 3
var s = mori.set(["foo", "bar", "baz"]);
mori.count(s) // 3
var m = mori.hashMap("foo", 1, "bar", 2);
mori.count(m) // 2
</pre>
</div>
<h3 id="isEmpty">
isEmpty
<span class="sig">mori.isEmpty(coll)</span>
</h3>
<p> Returns true if the collection is empty.</p>
<div class="example">
<pre class="brush: javascript">
var l = mori.list("foo", "bar", "baz");
mori.isEmpty(l); // => false
var v = mori.vector();
mori.isEmpty(v); // => true
</pre>
</div>
<h3 id="peek">
peek
<span class="sig">mori.peek(coll)</span>
</h3>
<p> Returns either the first item of a list or the last item of a vector.</p>
<div class="example">
<pre class="brush: javascript">
var l = mori.list("foo", "bar", "baz");
mori.peek(l) // "foo"
var v = mori.vector("foo", "bar", "baz");
mori.peek(v) // "baz"
</pre>
</div>
<h3 id="pop">
pop
<span class="sig">mori.pop(coll)</span>
</h3>
<p> Returns either a list with the first item removed or a vector with the last item removed.</p>
<div class="example">
<pre class="brush: javascript">
var l = mori.list("foo", "bar", "baz");
mori.pop(l) // ("bar" "baz")
var v = mori.vector("foo", "bar", "baz");
mori.pop(v) // ["foo" "bar"]
</pre>
</div>
<h3 id="zipmap">
zipmap
<span class="sig">mori.zipmap(seqable0, seqable1)</span>
</h3>
<p>
Takes two seqable objects and constructs a hash map. The first seqable provides the keys,
the second seqable the values.
</p>
<div class="example">
<pre class="brush: javascript">
var keys = ["foo", "bar", "baz"];
var vals = [1, 2, 3];
var h = mori.zipmap(keys, vals); // => {"foo" 1, "bar" 2, "baz" 3}
</pre>
</div>
<h3 id="reverse">
reverse
<span class="sig">mori.reverse(coll)</span>
</h3>
<p>
Returns a reversed sequence of a collection.
</p>
<div class="example">
<pre class="brush: javascript">
var v = mori.vector("foo", "bar", "baz");
mori.reverse(v); // => ["baz", "bar", "foo"]
</pre>
</div>
<h2 id="vector_operations">Vector Operations</h2>
<h3 id="subvec">
subvec
<span class="sig">mori.subvec(vector, start, [end])</span>
</h3>
<p>
Returns a subsection of a vector in constant time.
</p>
<div class="example">
<pre class="brush: javascript">
var v = mori.vector("cat", "dog", "bird", "zebra");
mori.subvec(v,1,2); // => ["dog"]
</pre>
</div>
<h2 id="hashMap_operations">Hash Map Operations</h2>
<h3 id="keys">
keys
<span class="sig">mori.keys(map)</span>
</h3>
<p>
Returns the keys of a hash map as a sequence.
</p>
<div class="example">
<pre class="brush: javascript">
var m = mori.hashMap("foo", 1, "bar", 2);
mori.intoArray(mori.keys(m)); // => [ "foo", "bar" ]
</pre>
</div>
<h3 id="vals">
vals
<span class="sig">mori.values(map)</span>
</h3>
<p>
Returns the values of a hash map as a sequence.
</p>
<div class="example">
<pre class="brush: javascript">
var m = mori.hashMap("foo", 1, "bar", 2);
mori.intoArray(mori.vals(m)); // => [ 1, 2 ]
</pre>
</div>
<h3 id="merge">
merge
<span class="sig">mori.merge(map, m0, m1, ...)</span>
</h3>
<p>
Returns the result of conj-ing the rest of the maps into the first map. If any of the keys
exist in the previous map, they will be overridden.
</p>
<div class="example">
<pre class="brush: javascript">
var m = mori.hashMap("foo", 1, "bar", 2);
mori.merge(m, mori.hashMap("bar", 3, "baz", 4)); // => {foo 1, bar 3, baz 4}
</pre>
</div>
<h2 id="set_operations">Set Operations</h2>
<h3 id="disj">
disj
<span class="sig">mori.disj(set)</span>
</h3>
<p>
Removes an element from a set.
</p>
<div class="example">
<pre class="brush: javascript">
var s = mori.set(["cat", "dog", "bird"]); // => #{"cat" "bird" "dog"}
mori.disj(s,"bird"); // => #{"dog" "cat"}
</pre>
</div>
<h3 id="union">
union
<span class="sig">mori.union(set0, set1, ...)</span>
</h3>
<p>
Returns the union of two sets.
</p>
<div class="example">
<pre class="brush: javascript">
var s0 = mori.set(["cat", "dog"]);
var s1 = mori.set(["zebra", "lion"]);
mori.union(s0, s1); // => #{"lion" "cat" "dog" "zebra"}
</pre>
</div>
<h3 id="intersection">
intersection
<span class="sig">mori.intersection(set0, set1, ...)</span>
</h3>
<p>
Returns the intersection of two sets.
</p>
<div class="example">
<pre class="brush: javascript">
var s0 = mori.set(["cat", "dog", "mouse"]);
var s1 = mori.set(["dog", "cat", "bird"]);
mori.intersection(s0, s1); // => #{"cat" "dog"}
</pre>
</div>
<h3 id="difference">
difference
<span class="sig">mori.difference(set0, set1, ...)</span>
</h3>
<p>
Returns the difference between two sets.
</p>
<div class="example">
<pre class="brush: javascript">
var s0 = mori.set(["cat", "dog", "mouse"]);
var s1 = mori.set(["dog", "cat", "bird"]);
mori.difference(s0, s1); // => #{"mouse" "bird"}
</pre>
</div>
<h3 id="isSubset">
isSubset
<span class="sig">mori.isSubset(seta, setb)</span>
</h3>
<p>
Returns true if <code>seta</code> is a subset of <code>setb</code>.
</p>
<div class="example">
<pre class="brush: javascript">
var s0 = mori.set(["dog", "cat"]);
var s1 = mori.set(["cat", "dog", "bird"]);
mori.isSubset(s0, s1); // => true
</pre>
</div>
<h3 id="isSuperset">
isSuperset
<span class="sig">mori.isSuperset(seta, setb)</span>
</h3>
<p>
Returns true if <code>seta</code> is a superset of <code>setb</code>.
</p>
<div class="example">
<pre class="brush: javascript">
var s0 = mori.set(["cat", "dog", "bird"]);
var s1 = mori.set(["dog", "cat"]);
mori.isSuperset(s0, s1); // => true
</pre>
</div>
<h2 id="sequences">Sequences</h2>
<h3 id="first">
first
<span class="sig">mori.first(coll)</span>
</h3>
<p>
Returns the first element in a collection.
</p>
<div class="example">
<pre class="brush: javascript">
mori.first("foobar"); // => "f"
mori.first([1,2,3]); // => 1
var l = mori.list(1,2,3);
mori.first(l); // => 1
var m = mori.hashMap("foo", 1, "bar", 2);
mori.first(m); // some key-value pair as an array
</pre>
</div>
<h3 id="rest">
rest
<span class="sig">mori.rest(coll)</span>
</h3>
<p>
Returns the remaining elements in a collection.
</p>
<div class="example">
<pre class="brush: javascript">
mori.rest("foobar"); // => ("o" "o" "b" "a" "r")
mori.rest([1,2,3]); // => (2 3)
var l = mori.list(1,2,3);
mori.rest(l); // => (2 3)
var m = mori.hashMap("foo", 1, "bar", 2);
mori.rest(m); // remaining key-value pairs
</pre>
</div>
<h3 id="seq">
seq
<span class="sig">mori.seq(coll)</span>
</h3>
<p>
Converts a collection whether Mori or JavaScript primitive
into a sequence.
</p>
<div class="example">
<pre class="brush: javascript">
mori.seq("foo"); // => ("f" "o" "o")
mori.seq(mori.list()); // => null
</pre>
</div>
<h3 id="cons">
cons
<span class="sig">mori.cons(val, coll)</span>
</h3>
<p>
Converts a collection into a sequence and adds a value to the
front.
</p>
<div class="example">
<pre class="brush: javascript">
var v = mori.vector(2, 3);
mori.cons(1, v); // => (1 2 3)
</pre>
</div>
<h3 id="concat">
concat
<span class="sig">mori.concat(coll0, coll1, ...)</span>
</h3>
<p>
Converts its arguments into sequences and concatenates them.
</p>
<div class="example">
<pre class="brush: javascript">
var r = mori.range(3);
var a = [3, 4, 5];
var l = mori.list(6, 7);
var v = mori.vector(8, 9);
mori.concat(r, a, l, v); // => (0 1 2 3 4 5 6 7 8 9)
</pre>
</div>
<h3 id="flatten">
flatten
<span class="sig">mori.flatten(coll)</span>
</h3>
<p>
Converts an arbitrarily nested collection into a flat
sequence.
</p>
<div class="example">
<pre class="brush: javascript">
var v = mori.toClj([[1, 2], 3, [4], [[5, 6], 7]]);
mori.flatten(v); // => (1 2 3 4 5 6 7)
</pre>
</div>
<h3 id="intoArray">
intoArray
<span class="sig">mori.intoArray(seq)</span>
</h3>
<p>
Converts a seqable collection, including Mori seqs back into a JavaScript array. Non-lazy.
</p>
<div class="example">
<pre class="brush: javascript">
var lazy = mori.map(mori.inc, [1,2,3]);
mori.intoArray(lazy); // => [2,3,4]
</pre>
</div>
<h3 id="each">
each
<span class="sig">mori.each(coll, f)</span>
</h3>
<p>
Iterate over a collection. For side effects.
</p>
<div class="example">
<pre class="brush: javascript">
var xs = mori.map(mori.inc, [1,2,3]);
mori.each(xs, function(n) {
console.log(n);
});
// will print 2 then 3 then 4 at your JS console
</pre>
</div>
<h3 id="map">
map
<span class="sig">mori.map(f, coll0, coll1, ...)</span>
</h3>
<p>
Return a lazy sequence that represents
the original collection with <code>f</code> applied to
each element. Note that map can take multiple collections
This obviates the need for Underscore.js's zip.
</p>
<div class="example">
<pre class="brush: javascript">
var a0 = [1,2,3];
mori.map(mori.inc, a0); // => (2 3 4)
var a1 = [4,5,6];
var a2 = [7,8,9];
mori.map(mori.vector, a0, a1, a2); // => ([1 4 7] [2 5 8] [3 6 9])
</pre>
</div>
<h3 id="mapcat">
mapcat
<span class="sig">mori.mapcat(f, coll0, coll1, ...)</span>
</h3>
<p>
Applies <code>f</code>, which must return a collection, to
each element of the original collection(s) and concatenates
the results into a single sequence.
</p>
<div class="example">
<pre class="brush: javascript">
var a = mori.seq("abc");
var b = mori.seq("123");
var f = function(x, y) { return mori.list(x, x + y); };
mori.mapcat(f, a, b); // => ("a", "a1", "b", "b2", "c", "c3")
mori.reduce(mori.concat, mori.map(f, a, b)); // => ("a", "a1", "b", "b2", "c", "c3")
</pre>
</div>
<h3 id="filter">
filter
<span class="sig">mori.filter(pred, coll)</span>
</h3>
<p>
Return a lazy sequence representing the original
collection filtered of elements which did not return a truthy
value for <code>pred</code>. Note that Mori has a stricter
notion of truth than JavaScript. Only false, undefined, and null
are considered false values.
</p>
<div class="example">
<pre class="brush: javascript">
var a = [0,1,2,3,4,5,7,7,9];
mori.filter(mori.isEven, a0); // => (0 2 4 6 8)
</pre>
</div>
<h3 id="remove">
remove
<span class="sig">mori.remove(pred, coll)</span>
</h3>
<p>
The inverse of filter. Return a lazy sequence representing the original
collction filtered of elements which returned a truthy
value for <code>pred</code>. Note that Mori has a stricter
notion of truth than JavaScript. Only false, undefined, and null
are considered false values.
</p>
<div class="example">
<pre class="brush: javascript">
var a = [0,1,2,3,4,5,6,7,9];
mori.remove(mori.isEven, a0); // => (1 3 5 7 9)
</pre>
</div>
<h3 id="reduce">
reduce
<span class="sig">mori.reduce(f, [intial], coll)</span>
</h3>
<p>
Accumulate a collection into a single value. <code>f</code>
should be a function of two arguments, the first will be the
accumulator, the second will be next value in the sequence.
</p>
<div class="example">
<pre class="brush: javascript">
var a = mori.range(10);
mori.reduce(mori.sum, 0, r); // => 45
</pre>
</div>
<h3 id="reduceKV">
reduceKV
<span class="sig">mori.reduceKV(f, [initial], map)</span>
</h3>
<p>
A variant of <code>reduce</code> for map-like collections,
specifically hash maps and vectors.
</p>
<div class="example">
<pre class="brush: javascript">
var f = function(acc, key, val) { return acc + "(" + key + ":" + val + ")"; };
var m = mori.hashMap("foo", 1, "bar", 2);
mori.reduceKV(f, "", m); // => "(foo:1)(bar:2)"
var v = mori.vector(5, 7);
mori.reduceKV(f, "", v); // => "(0:5)(1:7)"
</pre>
</div>
<h3 id="take">
take
<span class="sig">mori.take(n, coll)</span>
</h3>
<p>
Takes n elements from a colletion. Note that <code>coll</code>
could be an infinite sequence. This function returns
a lazy sequence.
</p>
<div class="example">
<pre class="brush: javascript">
var a = mori.range(); // infinite sequence
mori.take(10, r); // => (0 1 2 3 4 5 6 7 8 9)
</pre>
</div>
<h3 id="takeWhile">
takeWhile
<span class="sig">mori.takeWhile(pred, coll)</span>
</h3>
<p>
Takes elements from a collection as long as the
function <code>pred</code> returns a value other
than <code>false</code>, <code>null</code>
or <code>undefined</code>. Returns a lazy sequence.
</p>
<p>
The following example is in CoffeeScript:
</p>
<div class="example">
<pre class="brush: javascript">
a = [0,1,2,3,4,5,6,7,8,9]
mori.takeWhile ((n) -> n < 5), r // => (0 1 2 3 4)
</pre>
</div>
<h3 id="drop">
drop
<span class="sig">mori.drop(n, coll)</span>
</h3>
<p>
Drop n elements from a collection. Returns
a lazy sequence.
</p>
<div class="example">
<pre class="brush: javascript">
var a = [0,1,2,3,4,5,6,7,8,9]
mori.drop(5, a); // => (5 6 7 8 9)
</pre>
</div>
<h3 id="dropWhile">
dropWhile
<span class="sig">mori.interleave(pred, coll)</span>
</h3>
<p>
Drops elements from a collection as long as the
function <code>pred</code> returns a value other
than <code>false</code>, <code>null</code>
or <code>undefined</code>. Returns a lazy sequence.
</p>
<p>
The following example is in CoffeeScript:
</p>
<div class="example">
<pre class="brush: javascript">
a = [0,1,2,3,4,5,6,7,8,9]
mori.dropWhile ((n) -> n < 5), a // => (5 6 7 8 9)
</pre>
</div>
<h3 id="some">
some
<span class="sig">mori.some(pred, coll)</span>
</h3>
<p>
Applies the function <code>pred</code> to the elements of the
collection in order and returns the first result which is
not <code>false</code>, <code>null</code>
or <code>undefined</code>.
</p>
<div class="example">
<pre class="brush: javascript">
var a = [1,2,3,4,5,6,7,8,9];
var f = function(x) { return x % 5 == 0 && x * x; };
mori.some(f, a); // => 25
</pre>
</div>
<h3 id="every">
every
<span class="sig">mori.every(pred, coll)</span>
</h3>
<p>
Returns true if the result of applying the
function <code>pred</code> to an element of the collection is
never <code>false</code>, <code>null</code>
or <code>undefined</code>.
</p>
<div class="example">
<pre class="brush: javascript">
var a = [1,2,3,4,5,6,7,8,9];
var f = function(x) { return mori.isEven(x); };
var g = function(x) { return mori.isEven(x) || mori.isOdd(x); };
mori.every(f, a); // => false
mori.every(g, a); // => true
</pre>
</div>
<h3 id="sort">
sort
<span class="sig">mori.sort([cmp], coll)</span>
</h3>
<p>
Sorts the collection and returns a sequence. The comparison
function to be used can be given as the first argument.
</p>
<div class="example">
<pre class="brush: javascript">
var a = [4,6,2,7,1,0,9,5,8,3]
var f = function(a, b) { return b - a; };
mori.sort(a); // => (0 1 2 3 4 5 6 7 8 9)
mori.sort(f, a); // => (9 8 7 6 5 4 3 2 1 0)
</pre>
</div>
<h3 id="sortBy">
sortBy
<span class="sig">mori.sortBy(keyfn, [cmp], coll)</span>
</h3>
<p>
Sorts the collection by the values of <code>keyfn</code> on the
elements and returns a sequence. The comparison function to be
used can be given as the first argument.
</p>
<div class="example">
<pre class="brush: javascript">
var a = [0,1,2,3,4,5,6]
var kf = function(x) { return x * 5 % 7; };
var f = function(a, b) { return b - a; };
mori.map(kf, a); // => (0 5 3 1 6 4 2)
mori.sortBy(kf, a); // => (0 3 6 2 5 1 4)
mori.sortBy(kf, f, a); // => (4 1 5 2 3 6 0)
</pre>
</div>
<h3 id="interpose">
interpose
<span class="sig">mori.interpose(x, coll)</span>
</h3>
<p>
Interpose a value between all elements of a collection.
</p>
<div class="example">
<pre class="brush: javascript">
var a = [1,2,3]
mori.interpose("foo", a) // => (1 "foo" 2 "foo" 3)
</pre>
</div>
<h3 id="interleave">
interleave
<span class="sig">mori.interleave(coll0, coll1, ...)</span>
</h3>
<p>
Interleave two or more collections. The size of the resulting
lazy sequence is determined by the smallest collection.
</p>
<div class="example">
<pre class="brush: javascript">
var ns = [1,2,3];
var as = ["a", "b", "c"];
mori.interleave(ns, as); // => (1 "a" 2 "b" 3 "c")
</pre>
</div>
<h3 id="iterate">
iterate
<span class="sig">mori.iterate(f, x)</span>
</h3>
<p>
Creates a lazy sequences of x, f(x), f(f(x)), ...
</p>
<div class="example">
<pre class="brush: javascript">
mori.iterate(mor.inc, 0); // => (0 1 2 3 4 5 ...)
</pre>
</div>
<h3 id="repeat">
repeat
<span class="sig">mori.repeat([n], x)</span>
</h3>
<p>
Return a lazy of sequence of the value repeated.
If given <code>n</code>, the value will only be
repeated n times.
</p>
<p>
The following example is in CoffeeScript:
</p>
<div class="example">
<pre class="brush: javascript">
m = mori
foos = m.repeat("foo")
m.zipmap [1,2,3], foos // => {1 "foo", 2 "foo", 3 "foo"}
</pre>
</div>
<h3 id="repeatedly">
repeatedly
<span class="sig">mori.repeatedly([n], f)</span>
</h3>
<p>
Return a lazy of sequence of calling <code>f</code>, a
function which takes no arguments (presumably for side effects).
If given <code>n</code>, the function will only be
repeated n times.
</p>
<div class="example">
<pre class="brush: javascript">
mori.repeatedly(5, Math.random);
// => (... 5 random floating point numbers ...)
</pre>
</div>
<h3 id="partition">
partition
<span class="sig">mori.partition(n, [step], [pad], coll)</span>
</h3>
<p>
P