sortjs

a lightweight and convenient generator of sort functions for arrays of objects and objects of objects

npm install sortjs
13 downloads in the last week
14 downloads in the last month
<!DOCTYPE  html>
<html>
  <head>
    <meta charset="utf-8">
    
    <title>doc</title>
    <style>
      /*github.com style (c) Vasily Polovnyov <vast@whiteants.net>*/
      pre code {
        display: block; padding: 0.5em;
        color: #333;
        background: #f8f8ff
      }
      pre .comment,
      pre .template_comment,
      pre .diff .header,
      pre .javadoc {
        color: #998;
        font-style: italic
      }
      pre .keyword,
      pre .css .rule .keyword,
      pre .winutils,
      pre .javascript .title,
      pre .nginx .title,
      pre .subst,
      pre .request,
      pre .status {
        color: #333;
        font-weight: bold
      }
      pre .number,
      pre .hexcolor,
      pre .ruby .constant {
        color: #099;
      }
      pre .string,
      pre .tag .value,
      pre .phpdoc,
      pre .tex .formula {
        color: #d14
      }
      pre .title,
      pre .id {
        color: #900;
        font-weight: bold
      }
      pre .javascript .title,
      pre .lisp .title,
      pre .clojure .title,
      pre .subst {
        font-weight: normal
      }
      pre .class .title,
      pre .haskell .type,
      pre .vhdl .literal,
      pre .tex .command {
        color: #458;
        font-weight: bold
      }
      pre .tag,
      pre .tag .title,
      pre .rules .property,
      pre .django .tag .keyword {
        color: #000080;
        font-weight: normal
      }
      pre .attribute,
      pre .variable,
      pre .lisp .body {
        color: #008080
      }
      pre .regexp {
        color: #009926
      }
      pre .class {
        color: #458;
        font-weight: bold
      }
      pre .symbol,
      pre .ruby .symbol .string,
      pre .lisp .keyword,
      pre .tex .special,
      pre .prompt {
        color: #990073
      }
      pre .built_in,
      pre .lisp .title,
      pre .clojure .built_in {
        color: #0086b3
      }
      pre .preprocessor,
      pre .pi,
      pre .doctype,
      pre .shebang,
      pre .cdata {
        color: #999;
        font-weight: bold
      }
      pre .deletion {
        background: #fdd
      }
      pre .addition {
        background: #dfd
      }
      pre .diff .change {
        background: #0086b3
      }
      pre .chunk {
        color: #aaa
      }
    </style>
  </head>
  <body>  
    <h1>SortJS</h1>
<p>A lightweight and convenient generator of sort functions for
arrays of objects and objects of objects that works both on
server (NodeJS) and client (browser) sides.</p>
<p>Written by Vladimir Neverov <a href="&#x6d;&#x61;&#105;&#108;&#x74;&#x6f;&#x3a;&#115;&#x61;&#x6e;&#x67;&#117;&#105;&#x6e;&#105;&#64;&#103;&#x6d;&#97;&#105;&#x6c;&#x2e;&#99;&#x6f;&#109;">&#115;&#x61;&#x6e;&#x67;&#117;&#105;&#x6e;&#105;&#64;&#103;&#x6d;&#97;&#105;&#x6c;&#x2e;&#99;&#x6f;&#109;</a> in 2013.</p>
<p>Homepage: <a href="https://github.com/vne/sortjs/wiki"><a href="https://github.com/vne/sortjs/wiki">https://github.com/vne/sortjs/wiki</a></a></p>
<h2>Usage</h2>
<p>SortJS can be used to sort arrays of objects and objects of objects
by multiple properties. An array may look like this:</p>
<pre><code>var array = [
{ id: 1, surname: &#39;Smith&#39;, name: &#39;John&#39;, age: 30, income: 32000, percent: 55.3, birthday: new Date(&#39;09/18/2013&#39;), strdate: &quot;09/18/2013&quot; },
{ id: 2, surname: &#39;smith&#39;, name: &#39;Susanne&#39;, age: 28, income: 40000, percent: 55.1, birthday: new Date(&#39;09/18/2012&#39;), strdate: &quot;09/18/2012&quot; },
{ id: 3, surname: &#39;Bittey&#39;, name: &#39;Chris&#39;, age: 55, income: 20000, percent: 87.5, birthday: new Date(&#39;08/18/2011&#39;), strdate: &quot;08/18/2011&quot; },
{ id: 4, surname: &#39;The Fourth&#39;, name: &#39;Jane&#39;, age: 387, income: 150000, percent: 15.8, birthday: new Date(&#39;07/18/2010&#39;), strdate: &quot;07/18/2010&quot; },
{ id: 5, surname: &#39;Quinne&#39;, name: &#39;Stew&#39;, age: 5, income: 8500, percent: 31.7, birthday: new Date(&#39;09/18/2009&#39;), strdate: &quot;09/18/2009&quot; },
{ id: 6, surname: &#39;augsburg&#39;, name: &#39;Theodor&#39;, age: 154, income: 210000, percent: 99.9, birthday: new Date(&#39;09/18/2009&#39;), strdate: &quot;09/18/2009&quot; },
{ id: 7, surname: &#39;Zorro&#39;, name: &#39;Vasily&#39;, age: 30, income: 17000, percent: 7.3, birthday: new Date(&#39;12/18/2008&#39;), strdate: &quot;12/18/2008&quot; }
]</code></pre>
<p>An object may look like this:</p>
<pre><code>var obj = {
    1: { surname: &#39;Smith&#39;, name: &#39;John&#39;, age: 30, income: 32000, percent: 55.3 },
    2: { surname: &#39;smith&#39;, name: &#39;Susanne&#39;, age: 28, income: 40000, percent: 55.1 },
    3: { surname: &#39;Bittey&#39;, name: &#39;Chris&#39;, age: 55, income: 20000, percent: 87.5 },
    4: { surname: &#39;The Fourth&#39;, name: &#39;Jane&#39;, age: 387, income: 150000, percent: 15.8 },
    5: { surname: &#39;Quinne&#39;, name: &#39;Stew&#39;, age: 5, income: 8500, percent: 31.7 },
    6: { surname: &#39;augsburg&#39;, name: &#39;Theodor&#39;, age: 154, income: 210000, percent: 99.9 },
    7: { surname: &#39;Zorro&#39;, name: &#39;Vasily&#39;, age: 30, income: 17000, percent: 7.3 }
};</code></pre>
<p>Both can be sorted using SortJS. In case of an array you get a sorted array, in case of an
object you get a sorted array of object keys.</p>
<p>By default, SortJS returns a copy of a source array (as opposed to build-in Javascript method).
This behaviour can be altered.</p>
<h3>As a module (default)</h3>
<pre><code>var sortjs = require(&#39;sortjs&#39;);
var sortedArray = sortjs.sort(array, [&quot;surname&quot;, &quot;name&quot;]); // returns new array in requested order
var sortedObjKeys = sortjs.sort(obj, [&quot;surname&quot;, &quot;name&quot;]); // returns array of object keys sorted in requested order

sortjs.sort(array, [&quot;surname&quot;, &quot;name&quot;], true);             // perform an inplace sort like build-in Javascript method
sortjs.inplace(array, [&quot;surname&quot;, &quot;name&quot;]);                // another way of doing inplace sorting</code></pre>
<h3>As an Array or Object method (includes mangling of native objects prototypes!)</h3>
<pre><code>var sortjs = require(&#39;sortjs&#39;);
sortjs.improve();                                      // add .sortjs method to Array and Object prototypes
var sortedArray = array.sortjs([&quot;surname&quot;, &quot;name&quot;]); 
var sortedObjKeys = obj.sortjs([&quot;surname&quot;, &quot;name&quot;]);   // be careful, this returns keys of the object

sortjs.clear()                                         // remove added .sortjs method from Array and Object prototypes 

sortjs.improve(true);                                  // add .sortjs method to prototypes performing inplace sorting for arrays
array.sortjs([&quot;surname&quot;, &quot;name&quot;]);
sortjs.clear();

array.isortjs([&quot;surname&quot;, &quot;name&quot;]);                    // another way of doing inplace sorting</code></pre>
<h3>Simple get the sorter function</h3>
<pre><code>var sortjs = require(&#39;sortjs&#39;);
var sortFn = sortjs.getObjectSorter([&quot;surname&quot;, &quot;name&quot;]);</code></pre>
<h2>List of sort fields</h2>
<p>An array of property names should be specified to do the actual sort.
Property names are case-sensitive. They can have the following prefixes:</p>
<ul>
<li>&ndash;&nbsp;(minus sign) means reverse sorting by this property</li>
<li>i: (letter &#39;i&#39; followed by a colon) means case-insensitive string comparison by this property</li>
<li>s: (letter &#39;s&#39; followed by a colon) means case-sensitive string comparison by this property</li>
<li>n: (letter &#39;n&#39; followed by a colon) means integer comparison by this property</li>
<li>f: (letter &#39;f&#39; followed by a colon) means float comparison by this property</li>
<li>d: (letter &#39;d&#39; followed by a colon) means date comparison by this property</li>
</ul>
<p>Minus and one of the letters can be combined like this: &#39;-i:property&#39;. More than one letter prefix
is not allowed (and is not needed).</p>
<p>Examples:</p>
<ul>
<li>[&#39;i:surname&#39;, &#39;i:name&#39;, &#39;i:midname&#39;] - sort case-insensitevely by surname, then by name, then by midname</li>
<li>[&#39;-n:price&#39;, &#39;i:address&#39;] - reverse numerical (integer) sort by price, then case-insensitevely by address</li>
</ul>
<h2>Sorters and hinting</h2>
<p>sortjs.getObjectSorter returns different sorting functions for different field lists trying to avoid unnecessary 
comparisons and type conversions during actual sort. There are the following sorters:
 <em>  universal (U)     - includes all checks and therefore works correctly with all kinds of data
 </em>  with_flags (F)    - includes flag checks (i, s, n, etc)
 <em>  with_contexts (C) - includes callback/context access to fields that are compared
 </em>  single (1)        - the smallest function that is used for simple comparison by three fields or less (no cycle over fields)
 *  simple (S)        - simple comparison by any number of fields (cycle over fields)
Sorter is chosen automatically during field list processing. It assumes two points:
a) the field list is correct
b) the data in the array that should be sorted correspond to the field list provided
You can disable automatic choice by specifying which sorter should be used. This is done
as follows:</p>
<blockquote>
<p>sortjs.getObjectSorter(fieldList, { hint: &#39;U&#39; });</p>
</blockquote>
<p>This tells sortjs to return universal sorter regardless of its guesses about the data.</p>
<h2>Tests and examples</h2>
<p>More examples of library usage can be found in <strong>test.js</strong> file. To run tests you will
need <a href="http://visionmedia.github.io/mocha/">Mocha</a>, the tests themselves use built-in
NodeJS <a href="http://nodejs.org/api/assert.html">assert</a> module. To run tests in browser
open <strong>test.html</strong> file.</p>
<h2>Benchmarking</h2>
<p>TODO: explain</p>
<p>Array size = 1000, average over 500 samples</p>
<h2>Sparse data, single argument</h2>
<pre><code>        f |  0.85594 +/- 0.39481 ms | sorter 1 | rel( sortByF)  1.39450
      f:f |  1.23858 +/- 0.20522 ms | sorter F | rel( sortByF)  2.01788
  sortByF |  0.61380 +/- 0.08984 ms | sorter &lt;fn:_&gt;
        n |  0.81869 +/- 0.39290 ms | sorter 1 | rel( sortByN)  1.10172
      n:n |  1.93222 +/- 0.22229 ms | sorter F | rel( sortByN)  2.60019
      f:n |  1.24291 +/- 0.18595 ms | sorter F | rel( sortByN)  1.67258
  sortByN |  0.74311 +/- 1.03578 ms | sorter &lt;fn:_&gt;
        s |  1.02231 +/- 0.15645 ms | sorter 1 | rel( sortByS)  0.90074
      s:s |  2.23925 +/- 1.20828 ms | sorter F | rel( sortByS)  1.97296
  sortByS |  1.13497 +/- 1.14821 ms | sorter &lt;fn:_&gt;
        d |  6.97265 +/- 1.91867 ms | sorter 1 | rel( sortByD)  1.11903
      d:d | 13.62114 +/- 1.37493 ms | sorter F | rel( sortByD)  2.18604
  sortByD |  6.23096 +/- 0.41902 ms | sorter &lt;fn:_&gt;</code></pre>
<h2>Sparse data, four arguments</h2>
<p>   f,f2,f3,f4 |  1.01354 +/- 0.21947 ms | sorter S | rel(sortByFFFF)  1.87147
f: f,f2,f3,f4 |  1.41474 +/- 0.19859 ms | sorter F | rel(sortByFFFF)  2.61226
   sortByFFFF |  0.54158 +/- 0.04026 ms | sorter <fn:_></p>
<h2>Dense data, four arguments</h2>
<p>   f,f2,f3,f4 |  1.02665 +/- 0.14656 ms | sorter S | rel(sortByFFFF-D)  1.80118
f: f,f2,f3,f4 |  1.50496 +/- 0.33950 ms | sorter F | rel(sortByFFFF-D)  2.64035
 sortByFFFF-D |  0.56999 +/- 0.13108 ms | sorter <fn:_>
   n,n2,n3,n4 |  1.03933 +/- 0.48972 ms | sorter S | rel(sortByNNNN-D)  1.73908
n: n,n2,n3,n4 |  2.08253 +/- 0.40497 ms | sorter F | rel(sortByNNNN-D)  3.48466
f: n,n2,n3,n4 |  1.47462 +/- 0.51563 ms | sorter F | rel(sortByNNNN-D)  2.46745
 sortByNNNN-D |  0.59763 +/- 0.70503 ms | sorter <fn:_>
   s,s2,s3,s4 |  1.29927 +/- 0.40556 ms | sorter S | rel(sortBySSSS-D)  1.36926
s: s,s2,s3,s4 |  1.93002 +/- 0.66550 ms | sorter F | rel(sortBySSSS-D)  2.03400
 sortBySSSS-D |  0.94888 +/- 0.21068 ms | sorter <fn:_>
   d,d2,d3,d4 | 14.40979 +/- 1.49310 ms | sorter S | rel(sortByDDDD-D)  2.19868
d: d,d2,d3,d4 | 26.66083 +/- 2.93955 ms | sorter F | rel(sortByDDDD-D)  4.06797
 sortByDDDD-D |  6.55384 +/- 1.18187 ms | sorter <fn:_></p>

  </body>
</html>
npm loves you