supergroup
Version:
Nested groups on arrays of objects where groups are Strings that know what you want them to know about themselves and their relatives.
341 lines (322 loc) • 82.6 kB
HTML
<!DOCTYPE html><html lang="en" class="two-column-layout"><head><title>index</title></head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"><meta name="groc-relative-root" content=""><meta name="groc-document-path" content="index"><meta name="groc-project-path" content="supergroup.js"><link rel="stylesheet" type="text/css" media="all" href="assets/style.css"><script type="text/javascript" src="assets/behavior.js"></script><body><div id="meta"><div class="file-path">supergroup.js</div></div><div id="document"><div class="segment"><div class="comments "><div class="wrapper"><h1 id="supergroupjs">supergroup.js</h1>
<p>Author: <a href="http://sigfried.org">Sigfried Gold</a> <br />
License: <a href="http://sigfried.mit-license.org/">MIT</a> </p>
<p>usage examples at <a href="http://sigfried.github.io/blog/supergroup">http://sigfried.github.io/blog/supergroup</a></p></div></div><div class="code"><div class="wrapper"><span class="p">;</span> <span class="c1">// jshint -W053</span>
<span class="s1">'use strict()'</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="nx">require</span><span class="p">)</span> <span class="o">!==</span> <span class="s2">"undefined"</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// make it work in node or browsers or other contexts</span>
<span class="nx">_</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'underscore'</span><span class="p">);</span> <span class="c1">// otherwise assume it was included by html file</span>
<span class="nx">require</span><span class="p">(</span><span class="s1">'underscore-unchained'</span><span class="p">);</span> <span class="c1">// adds unchain as an Underscore mixin</span>
<span class="nx">require</span><span class="p">(</span><span class="s1">'1670507/underscoreAddon.js'</span><span class="p">);</span> <span class="c1">// adds mean, median, etc. as mixins</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">supergroup</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">e</span> <span class="o">=</span> <span class="p">{};</span> <span class="c1">// local reference to supergroup namespace</span></div></div></div><div class="segment"><div class="comments doc-section"><div class="wrapper"><p><span class='doc-section-header'> class List</span></p>
<p>Native Array of groups with various added methods and properties.
Methods described below.</p></div></div><div class="code"><div class="wrapper"> <span class="kd">function</span> <span class="nx">List</span><span class="p">()</span> <span class="p">{}</span></div></div></div><div class="segment"><div class="comments doc-section"><div class="wrapper"><p><span class='doc-section-header'> class Value</span></p>
<p>Supergroup Lists are composed of Values which are
String or Number objects representing group values.
Methods described below.</p></div></div><div class="code"><div class="wrapper"> <span class="kd">function</span> <span class="nx">Value</span><span class="p">()</span> <span class="p">{}</span></div></div></div><div class="segment"><div class="comments doc-section"><div class="wrapper"><p><span class='doc-section-header'> exported function supergroup.group(recs, dim, opts)</span></p>
<p>Parameters:</p>
<ul>
<li><p><strong>recs must be an Array of Objects.</strong><br/>(list of records to be grouped)</p></li>
<li><p><strong>dim must be a string or Function.</strong><br/>(either the property name to group by or a function returning a group by string or number)</p></li>
<li><p><strong>opts is optional and must be an Object.</strong></p>
<ul><li><p><strong>opts.childProp must be a String and has a default value of 'children'.</strong><br/>(If group ends up being hierarchical, this will be the property name of any children)</p></li>
<li><p><strong>opts.excludeValues is optional and must be an Array of Strings.</strong><br/>(to exlude specific group values)</p></li>
<li><p><strong>opts.preListRecsHook is optional and must be a function.</strong><br/>(run recs through this function before continuing processing)</p></li>
<li><p><strong>opts.dimName is optional and must be a function.</strong><br/>(defaults to the value of <code>dim</code>. If <code>dim</code> is a function, the dimName will be ugly.)</p></li></ul></li>
</ul>
<p><strong>Returns an Array of Values</strong><br/>(enhanced with all the List methods Avaailable as _.supergroup, Underscore mixin)</p></div></div><div class="code"><div class="wrapper"> <span class="nx">e</span><span class="p">.</span><span class="nx">group</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">recs</span><span class="p">,</span> <span class="nx">dim</span><span class="p">,</span> <span class="nx">opts</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">dim</span><span class="p">).</span><span class="nx">isArray</span><span class="p">())</span> <span class="k">return</span> <span class="nx">e</span><span class="p">.</span><span class="nx">multiDimList</span><span class="p">(</span><span class="nx">recs</span><span class="p">,</span> <span class="nx">dim</span><span class="p">,</span> <span class="nx">opts</span><span class="p">);</span> <span class="c1">// handoff to multiDimmList if dim is an array</span>
<span class="nx">opts</span> <span class="o">=</span> <span class="nx">opts</span> <span class="o">||</span> <span class="p">{};</span>
<span class="nx">recs</span> <span class="o">=</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">preListRecsHook</span> <span class="o">?</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">preListRecsHook</span><span class="p">(</span><span class="nx">recs</span><span class="p">)</span> <span class="o">:</span> <span class="nx">recs</span><span class="p">;</span>
<span class="nx">childProp</span> <span class="o">=</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">childProp</span> <span class="o">||</span> <span class="nx">childProp</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">groups</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">groupBy</span><span class="p">(</span><span class="nx">recs</span><span class="p">,</span> <span class="nx">dim</span><span class="p">);</span> <span class="c1">// use Underscore's groupBy: http://underscorejs.org/#groupBy</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">opts</span><span class="p">.</span><span class="nx">excludeValues</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">opts</span><span class="p">.</span><span class="nx">excludeValues</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">delete</span> <span class="nx">groups</span><span class="p">[</span><span class="nx">d</span><span class="p">];</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">isNumeric</span> <span class="o">=</span> <span class="nx">wholeListNumeric</span><span class="p">(</span><span class="nx">groups</span><span class="p">);</span> <span class="c1">// does every group Value look like a number or a missing value?</span>
<span class="kd">var</span> <span class="nx">groups</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">pairs</span><span class="p">(</span><span class="nx">groups</span><span class="p">),</span> <span class="kd">function</span><span class="p">(</span><span class="nx">pair</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// setup Values for each group in List</span>
<span class="kd">var</span> <span class="nx">rawVal</span> <span class="o">=</span> <span class="nx">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">val</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span><span class="nx">isNumeric</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">val</span> <span class="o">=</span> <span class="nx">makeNumberValue</span><span class="p">(</span><span class="nx">rawVal</span><span class="p">);</span> <span class="c1">// either everything's a Number</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">val</span> <span class="o">=</span> <span class="nx">makeStringValue</span><span class="p">(</span><span class="nx">rawVal</span><span class="p">);</span> <span class="c1">// or everything's a String</span>
<span class="p">}</span></div></div></div><div class="segment"><div class="comments "><div class="wrapper"><p>The original records in this group are stored as an Array in
the records property (should probably be a getter method).</p></div></div><div class="code"><div class="wrapper"> <span class="nx">val</span><span class="p">.</span><span class="nx">records</span> <span class="o">=</span> <span class="nx">pair</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span></div></div></div><div class="segment"><div class="comments "><div class="wrapper"><p>val.records is enhanced with Underscore methods for
convenience, but also with the supergroup method that's
been mixed in to Underscore. So you can group this specific
subset like: val.records.supergroup
on FIX!!!!!!</p></div></div><div class="code"><div class="wrapper"> <span class="nx">_</span><span class="p">.</span><span class="nx">unchain</span><span class="p">(</span><span class="nx">val</span><span class="p">.</span><span class="nx">records</span><span class="p">);</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">dim</span> <span class="o">=</span> <span class="p">(</span><span class="nx">opts</span><span class="p">.</span><span class="nx">dimName</span><span class="p">)</span> <span class="o">?</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">dimName</span> <span class="o">:</span> <span class="nx">dim</span><span class="p">;</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">records</span><span class="p">.</span><span class="nx">parentVal</span> <span class="o">=</span> <span class="nx">val</span><span class="p">;</span> <span class="c1">// NOT TESTED, NOT USED, PROBABLY WRONG</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">opts</span><span class="p">.</span><span class="nx">parent</span><span class="p">)</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">parent</span> <span class="o">=</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">parent</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">val</span><span class="p">.</span><span class="nx">parent</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="s1">'depth'</span> <span class="k">in</span> <span class="nx">val</span><span class="p">.</span><span class="nx">parent</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">depth</span> <span class="o">=</span> <span class="nx">val</span><span class="p">.</span><span class="nx">parent</span><span class="p">.</span><span class="nx">depth</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">parent</span><span class="p">.</span><span class="nx">depth</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">depth</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">depth</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">val</span><span class="p">;</span>
<span class="p">});</span>
<span class="nx">groups</span> <span class="o">=</span> <span class="nx">makeList</span><span class="p">(</span><span class="nx">groups</span><span class="p">);</span>
<span class="nx">groups</span><span class="p">.</span><span class="nx">records</span> <span class="o">=</span> <span class="nx">recs</span><span class="p">;</span> <span class="c1">// NOT TESTED, NOT USED, PROBABLY WRONG</span>
<span class="nx">groups</span><span class="p">.</span><span class="nx">dim</span> <span class="o">=</span> <span class="p">(</span><span class="nx">opts</span><span class="p">.</span><span class="nx">dimName</span><span class="p">)</span> <span class="o">?</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">dimName</span> <span class="o">:</span> <span class="nx">dim</span><span class="p">;</span>
<span class="nx">groups</span><span class="p">.</span><span class="nx">isNumeric</span> <span class="o">=</span> <span class="nx">isNumeric</span><span class="p">;</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">groups</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">group</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">group</span><span class="p">.</span><span class="nx">parentList</span> <span class="o">=</span> <span class="nx">groups</span><span class="p">;</span>
<span class="p">});</span></div></div></div><div class="segment"><div class="comments "><div class="wrapper"><p>pointless without recursion</p></div></div><div class="code"><div class="wrapper"> <span class="c1">//if (opts.postListListHook) groups = opts.postListListHook(groups);</span>
<span class="k">return</span> <span class="nx">groups</span><span class="p">;</span>
<span class="p">};</span>
<span class="nx">e</span><span class="p">.</span><span class="nx">multiDimList</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">recs</span><span class="p">,</span> <span class="nx">dims</span><span class="p">,</span> <span class="nx">opts</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">groups</span> <span class="o">=</span> <span class="nx">e</span><span class="p">.</span><span class="nx">group</span><span class="p">(</span><span class="nx">recs</span><span class="p">,</span> <span class="nx">dims</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">opts</span><span class="p">);</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">chain</span><span class="p">(</span><span class="nx">dims</span><span class="p">).</span><span class="nx">rest</span><span class="p">().</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">dim</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">groups</span><span class="p">.</span><span class="nx">addLevel</span><span class="p">(</span><span class="nx">dim</span><span class="p">,</span> <span class="nx">opts</span><span class="p">);</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">groups</span><span class="p">;</span>
<span class="p">};</span>
<span class="nx">List</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">asRootVal</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">dimName</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">name</span> <span class="o">=</span> <span class="nx">name</span> <span class="o">||</span> <span class="s1">'Root'</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">val</span> <span class="o">=</span> <span class="nx">makeValue</span><span class="p">(</span><span class="nx">name</span><span class="p">);</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">records</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span> <span class="c1">// is this wrong?</span>
<span class="nx">val</span><span class="p">[</span><span class="nx">childProp</span><span class="p">]</span><span class="o">=</span> <span class="k">this</span><span class="p">;</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">descendants</span><span class="p">().</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span> <span class="nx">d</span><span class="p">.</span><span class="nx">depth</span> <span class="o">=</span> <span class="nx">d</span><span class="p">.</span><span class="nx">depth</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="p">});</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">depth</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">dim</span> <span class="o">=</span> <span class="nx">dimName</span> <span class="o">||</span> <span class="s1">'root'</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">val</span><span class="p">;</span>
<span class="p">};</span>
<span class="nx">List</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">leafNodes</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">level</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">invoke</span><span class="p">(</span><span class="s1">'leafNodes'</span><span class="p">).</span><span class="nx">flatten</span><span class="p">();</span>
<span class="p">};</span>
<span class="nx">List</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">rawValues</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">map</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">d</span><span class="p">.</span><span class="nx">toString</span><span class="p">();</span> <span class="p">});</span>
<span class="p">};</span>
<span class="nx">List</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">lookup</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">query</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isArray</span><span class="p">(</span><span class="nx">query</span><span class="p">))</span> <span class="p">{</span></div></div></div><div class="segment"><div class="comments "><div class="wrapper"><p>if group has children, can search down the tree</p></div></div><div class="code"><div class="wrapper"> <span class="kd">var</span> <span class="nx">values</span> <span class="o">=</span> <span class="nx">query</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">list</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">ret</span><span class="p">;</span>
<span class="k">while</span><span class="p">(</span><span class="nx">values</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">ret</span> <span class="o">=</span> <span class="nx">list</span><span class="p">.</span><span class="nx">singleLookup</span><span class="p">(</span><span class="nx">values</span><span class="p">.</span><span class="nx">shift</span><span class="p">());</span>
<span class="nx">list</span> <span class="o">=</span> <span class="nx">ret</span><span class="p">[</span><span class="nx">childProp</span><span class="p">];</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">ret</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">singleLookup</span><span class="p">(</span><span class="nx">query</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="nx">List</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">singleLookup</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">query</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">that</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span> <span class="p">(</span><span class="s1">'lookupMap'</span> <span class="k">in</span> <span class="k">this</span><span class="p">))</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">lookupMap</span> <span class="o">=</span> <span class="p">{};</span>
<span class="k">this</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">that</span><span class="p">.</span><span class="nx">lookupMap</span><span class="p">[</span><span class="nx">d</span><span class="p">]</span> <span class="o">=</span> <span class="nx">d</span><span class="p">;</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">query</span> <span class="k">in</span> <span class="k">this</span><span class="p">.</span><span class="nx">lookupMap</span><span class="p">)</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">lookupMap</span><span class="p">[</span><span class="nx">query</span><span class="p">];</span>
<span class="p">};</span>
<span class="nx">List</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">flattenTree</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">chain</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
<span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">desc</span> <span class="o">=</span> <span class="nx">d</span><span class="p">.</span><span class="nx">descendants</span><span class="p">();</span>
<span class="k">return</span> <span class="p">[</span><span class="nx">d</span><span class="p">].</span><span class="nx">concat</span><span class="p">(</span><span class="nx">desc</span><span class="p">);</span>
<span class="p">})</span>
<span class="p">.</span><span class="nx">flatten</span><span class="p">()</span>
<span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">identity</span><span class="p">)</span> <span class="c1">// expunge nulls</span>
<span class="p">.</span><span class="nx">tap</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">addListMethods</span><span class="p">)</span>
<span class="p">.</span><span class="nx">value</span><span class="p">();</span>
<span class="p">};</span>
<span class="nx">List</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">addLevel</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">dim</span><span class="p">,</span> <span class="nx">opts</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">val</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">addLevel</span><span class="p">(</span><span class="nx">dim</span><span class="p">,</span> <span class="nx">opts</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">};</span>
<span class="kd">function</span> <span class="nx">makeList</span><span class="p">(</span><span class="nx">arr_arg</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[</span> <span class="p">];</span>
<span class="nx">arr</span><span class="p">.</span><span class="nx">push</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">arr_arg</span><span class="p">);</span>
<span class="c1">//arr.__proto__ = List.prototype;</span>
<span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">method</span> <span class="k">in</span> <span class="nx">List</span><span class="p">.</span><span class="nx">prototype</span><span class="p">)</span> <span class="p">{</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">method</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="nx">List</span><span class="p">.</span><span class="nx">prototype</span><span class="p">[</span><span class="nx">method</span><span class="p">]</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">unchain</span><span class="p">(</span><span class="nx">arr</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">arr</span><span class="p">;</span>
<span class="p">}</span></div></div></div><div class="segment"><div class="comments doc-section"><div class="wrapper"><p><span class='doc-section-header'> memberof enlightenedData </p>
<pre><code>e.addUnderscoreMethods = function(arr) {
_(e.underscoreMethodsToAddToArrays).each(function(methodName) {
if (_(arr).has(methodName)) return;
Object.defineProperty(arr, methodName, {
value: function() {
var part = _.partial(_[methodName], arr);
var result = part.apply(null, _.toArray(arguments));
if (_.isArray(result)) e.addListMethods(result);
return result;
}});
});
return arr;
};
e.underscoreMethodsToAddToArrays = [
"each",
"map",
"reduce",
"find",
"filter",
"reject",
"all",
"every",
"any",
"some",
"contains",
"invoke",
"pluck",
"where",
"findWhere",
"max",
"min",
"shuffle",
"sortBy",
"groupBy",
"countBy",
"sortedIndex",
"size",
"first",
"initial",
"last",
"rest",
"compact",
"flatten",
"without",
"uniq",
"union",
"intersection",
"difference",
"zip",
"unzip",
//"object",
"indexOf",
"lastIndexOf",
"chain",
"result"
];</span>
</code></pre>
<p>Enhance arrays with {@link http://underscorejs.org/ Underscore} functions
that work on arrays. </p>
<p>Parameters:</p>
<ul>
<li><strong>arr must be an Array.</strong></li>
</ul>
<p><strong>Returns an Array</strong><br/>(now enhanced Now can call Underscore functions as methods on the array, and if the return value is an array, it will also be enhanced.)<br/><strong>and</strong> <strong>Returns a whatever the underscore function would return</strong></p>
<p>Example:</p>
<p>`enlightenedData.addUnderscoreMethods(['a','bb','ccc'])
.pluck('length')
.
group.where({foo:bar}).invoke('baz')</p></div></div><div class="code"><div class="wrapper"> <span class="kd">function</span> <span class="nx">makeValue</span><span class="p">(</span><span class="nx">v_arg</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">isNaN</span><span class="p">(</span><span class="nx">v_arg</span><span class="p">))</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">makeStringValue</span><span class="p">(</span><span class="nx">v_arg</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">makeNumberValue</span><span class="p">(</span><span class="nx">v_arg</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">StringValue</span><span class="p">()</span> <span class="p">{}</span>
<span class="c1">//StringValue.prototype = new String;</span>
<span class="kd">function</span> <span class="nx">makeStringValue</span><span class="p">(</span><span class="nx">s_arg</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">S</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">String</span><span class="p">(</span><span class="nx">s_arg</span><span class="p">);</span>
<span class="c1">//S.__proto__ = StringValue.prototype; // won't work in IE10</span>
<span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">method</span> <span class="k">in</span> <span class="nx">StringValue</span><span class="p">.</span><span class="nx">prototype</span><span class="p">)</span> <span class="p">{</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nx">S</span><span class="p">,</span> <span class="nx">method</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="nx">StringValue</span><span class="p">.</span><span class="nx">prototype</span><span class="p">[</span><span class="nx">method</span><span class="p">]</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">S</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">NumberValue</span><span class="p">()</span> <span class="p">{}</span>
<span class="c1">//NumberValue.prototype = new Number;</span>
<span class="kd">function</span> <span class="nx">makeNumberValue</span><span class="p">(</span><span class="nx">n_arg</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">N</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Number</span><span class="p">(</span><span class="nx">n_arg</span><span class="p">);</span>
<span class="c1">//N.__proto__ = NumberValue.prototype;</span>
<span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">method</span> <span class="k">in</span> <span class="nx">NumberValue</span><span class="p">.</span><span class="nx">prototype</span><span class="p">)</span> <span class="p">{</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nx">N</span><span class="p">,</span> <span class="nx">method</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="nx">NumberValue</span><span class="p">.</span><span class="nx">prototype</span><span class="p">[</span><span class="nx">method</span><span class="p">]</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">N</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">wholeListNumeric</span><span class="p">(</span><span class="nx">groups</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">isNumeric</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">every</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">groups</span><span class="p">),</span> <span class="kd">function</span><span class="p">(</span><span class="nx">k</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">k</span> <span class="o">===</span> <span class="kc">null</span> <span class="o">||</span>
<span class="nx">k</span> <span class="o">===</span> <span class="kc">undefined</span> <span class="o">||</span>
<span class="p">(</span><span class="o">!</span><span class="nb">isNaN</span><span class="p">(</span><span class="nb">Number</span><span class="p">(</span><span class="nx">k</span><span class="p">)))</span> <span class="o">||</span>
<span class="p">[</span><span class="s2">"null"</span><span class="p">,</span> <span class="s2">"."</span><span class="p">,</span> <span class="s2">"undefined"</span><span class="p">].</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">k</span><span class="p">.</span><span class="nx">toLowerCase</span><span class="p">())</span> <span class="o">></span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="p">});</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">isNumeric</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">groups</span><span class="p">),</span> <span class="kd">function</span><span class="p">(</span><span class="nx">k</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">isNaN</span><span class="p">(</span><span class="nx">k</span><span class="p">))</span> <span class="p">{</span>
<span class="k">delete</span> <span class="nx">groups</span><span class="p">[</span><span class="nx">k</span><span class="p">];</span> <span class="c1">// getting rid of NULL values in dim list!!</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">isNumeric</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">childProp</span> <span class="o">=</span> <span class="s1">'children'</span><span class="p">;</span>
<span class="nx">Value</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">extendGroupBy</span> <span class="o">=</span> <span class="c1">// backward compatibility</span>
<span class="nx">Value</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">addLevel</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">dim</span><span class="p">,</span> <span class="nx">opts</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">opts</span> <span class="o">=</span> <span class="nx">opts</span> <span class="o">||</span> <span class="p">{};</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">leafNodes</span><span class="p">(),</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">opts</span><span class="p">.</span><span class="nx">parent</span> <span class="o">=</span> <span class="nx">d</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">d</span><span class="p">.</span><span class="k">in</span> <span class="o">&&</span> <span class="nx">d</span><span class="p">.</span><span class="k">in</span> <span class="o">===</span> <span class="s2">"both"</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">d</span><span class="p">[</span><span class="nx">childProp</span><span class="p">]</span> <span class="o">=</span> <span class="nx">e</span><span class="p">.</span><span class="nx">diffList</span><span class="p">(</span><span class="nx">d</span><span class="p">.</span><span class="nx">from</span><span class="p">,</span> <span class="nx">d</span><span class="p">.</span><span class="nx">to</span><span class="p">,</span> <span class="nx">dim</span><span class="p">,</span> <span class="nx">opts</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">d</span><span class="p">[</span><span class="nx">childProp</span><span class="p">]</span> <span class="o">=</span> <span class="nx">e</span><span class="p">.</span><span class="nx">group</span><span class="p">(</span><span class="nx">d</span><span class="p">.</span><span class="nx">records</span><span class="p">,</span> <span class="nx">dim</span><span class="p">,</span> <span class="nx">opts</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">d</span><span class="p">.</span><span class="k">in</span> <span class="p">)</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">d</span><span class="p">[</span><span class="nx">childProp</span><span class="p">]).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">c</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">c</span><span class="p">.</span><span class="k">in</span> <span class="o">=</span> <span class="nx">d</span><span class="p">.</span><span class="k">in</span><span class="p">;</span>
<span class="nx">c</span><span class="p">[</span><span class="nx">d</span><span class="p">.</span><span class="k">in</span><span class="p">]</span> <span class="o">=</span> <span class="nx">d</span><span class="p">[</span><span class="nx">d</span><span class="p">.</span><span class="k">in</span><span class="p">];</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nx">d</span><span class="p">[</span><span class="nx">childProp</span><span class="p">].</span><span class="nx">parentVal</span> <span class="o">=</span> <span class="nx">d</span><span class="p">;</span> <span class="c1">// NOT TESTED, NOT USED, PROBABLY WRONG!!!</span>
<span class="p">});</span>
<span class="p">};</span>
<span class="nx">Value</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">leafNodes</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">level</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">ret</span> <span class="o">=</span> <span class="p">[</span><span class="k">this</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">level</span> <span class="o">===</span> <span class="s2">"undefined"</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">level</span> <span class="o">=</span> <span class="kc">Infinity</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">level</span> <span class="o">!==</span> <span class="mi">0</span> <span class="o">&&</span> <span class="k">this</span><span class="p">[</span><span class="nx">childProp</span><span class="p">]</span> <span class="o">&&</span> <span class="p">(</span><span class="o">!</span><span class="nx">level</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">depth</span> <span class="o"><</span> <span class="nx">level</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">ret</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">flatten</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="k">this</span><span class="p">[</span><span class="nx">childProp</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">c</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">c</span><span class="p">.</span><span class="nx">leafNodes</span><span class="p">(</span><span class="nx">level</span><span class="p">);</span>
<span class="p">}),</span> <span class="kc">true</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">makeList</span><span class="p">(</span><span class="nx">ret</span><span class="p">);</span>
<span class="p">};</span></div></div></div><div class="segment"><div class="comments "><div class="wrapper"><p>didn't make this yet, just copied from above
Value.prototype.descendants = function(level) {
var ret = [this];
if (level !== 0 && this[childProp] && (!level || this.depth < level))
ret = <em>.flatten(</em>.map(this[childProp], function(c) {
return c.leafNodes(level);
}), true);
return makeList(ret);
};</p></div></div><div class="code"><div class="wrapper"> <span class="kd">function</span> <span class="nx">delimOpts</span><span class="p">(</span><span class="nx">opts</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">opts</span> <span class="o">===</span> <span class="s2">"string"</span><span class="p">)</span> <span class="nx">opts</span> <span class="o">=</span> <span class="p">{</span><span class="nx">delim</span><span class="o">:</span> <span class="nx">opts</span><span class="p">};</span>
<span class="nx">opts</span> <span class="o">=</span> <span class="nx">opts</span> <span class="o">||</span> <span class="p">{};</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">(</span><span class="nx">opts</span><span class="p">).</span><span class="nx">has</span><span class="p">(</span><span class="s1">'delim'</span><span class="p">))</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">delim</span> <span class="o">=</span> <span class="s1">'/'</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">opts</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">Value</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">dimPath</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">opts</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">opts</span> <span class="o">=</span> <span class="nx">delimOpts</span><span class="p">(</span><span class="nx">opts</span><span class="p">);</span>
<span class="nx">opts</span><span class="p">.</span><span class="nx">dimName</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">namePath</span><span class="p">(</span><span class="nx">opts</span><span class="p">);</span>
<span class="p">};</span>
<span class="nx">Value</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">namePath</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">opts</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">opts</span> <span class="o">=</span> <span class="nx">delimOpts</span><span class="p">(</span><span class="nx">opts</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">path</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">pedigree</span><span class="p">(</span><span class="nx">opts</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">opts</span><span class="p">.</span><span class="nx">noRoot</span><span class="p">)</span> <span class="nx">path</span><span class="p">.</span><span class="nx">shift</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">opts</span><span class="p">.</span><span class="nx">backwards</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">backwards</span><span class="p">)</span> <span class="nx">path</span><span class="p">.</sp