1 | <!DOCTYPE html>
|
2 | <html>
|
3 | <head>
|
4 | <meta charset="utf-8">
|
5 | <link rel="stylesheet" href="assets/style.css?t=a44c9e9d">
|
6 | <link rel="stylesheet" href="http://ricostacruz.com/docpress-rsc/style.css">
|
7 | <script src="assets/script.js?t=2bcc4b59"></script>
|
8 | <title>scour.js</title>
|
9 | <meta name="viewport" content="width=device-width">
|
10 | <script>
|
11 | if (false || window.location.hostname.indexOf("ricostacruz.com") === window.location.hostname.length - 15) {
|
12 | (function(d,o,c,p,r,e,s){d['GoogleAnalyticsObject']=r;d[r]=d[r]||function(){(d[r].q=d[r].q||[]).push(arguments)},d[r].l=1*new Date();e=o.createElement(c),s=o.getElementsByTagName(c)[0];e.async=1;e.src=p;s.parentNode.insertBefore(e,s)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
13 | ga('create',"UA-20473929-1",'auto')
|
14 | }
|
15 | </script>
|
16 | </head>
|
17 | <body class="-menu-visible">
|
18 | <div class="doc-layout">
|
19 | <div class="toggle menu-toggle js-menu-toggle"></div>
|
20 | <div class="body page-index">
|
21 | <div class="header-nav">
|
22 | <div class="right"><a href="https://github.com/rstacruz/scour" data-title="rstacruz/scour" class="iconlink">
|
23 | <span class="icon -github"></span></a>
|
24 | </div>
|
25 | </div>
|
26 | <div class="markdown-body"><h1 class="massive-header -with-tagline" id="scour.js">scour.js</h1>
|
27 | <blockquote>
|
28 | <p>Traverse objects and arrays immutably</p>
|
29 | </blockquote>
|
30 | <p>Scour is a general-purpose library for dealing with JSON trees.<br>
|
31 | As a simple utility with a broad purpose, it can be used to solve many problems. Use it to:</p>
|
32 | <ul>
|
33 | <li>Manage your <a href="http://rackt.github.io/redux">Redux</a> datastore.</li>
|
34 | <li>Provide a model layer to access data in your single-page app. <a href="#models">→</a></li>
|
35 | <li>Navigate a large JSON tree easily.</li>
|
36 | <li>Rejoice in having a lightweight alternative to <a href="http://facebook.github.io/immutable-js/">Immutable.js</a>. (<a href="comparison.html">Compare</a>)</li>
|
37 | </ul>
|
38 | <p><a href="https://travis-ci.org/rstacruz/scour" title="See test builds"><img src="https://travis-ci.org/rstacruz/scour.svg?branch=master" alt="Status"></a></p>
|
39 | <h2 id="install">Install</h2>
|
40 | <pre><code class="lang-sh">npm install --save-exact scourjs
|
41 | </code></pre>
|
42 | <pre><code class="lang-js"><span class="pl-c1">window</span>.scour <span class="pl-c">// non commonjs</span>
|
43 | <span class="pl-k">const</span> scour = <span class="pl-c1">require</span>(<span class="pl-s">'scourjs'</span>) <span class="pl-c">// commonjs/node</span>
|
44 | <span class="pl-k">import</span> scour <span class="pl-k">from</span> <span class="pl-s">'scourjs'</span> // es6 modules
|
45 | </code></pre>
|
46 | <h2 id="features">Features</h2>
|
47 | <p>Calling <code>scour(object)</code> returns a wrapper that you can use to traverse <code>object</code>.
|
48 | Use <a href="#get">get()</a> to retrieve values.</p>
|
49 | <pre><code class="lang-js">data =
|
50 | { users:
|
51 | { <span class="hljs-number">1</span>: { name: <span class="pl-s">'john'</span> },
|
52 | <span class="hljs-number">2</span>: { name: <span class="pl-s">'shane'</span>, confirmed: <span class="pl-c1">true</span> },
|
53 | <span class="hljs-number">3</span>: { name: <span class="pl-s">'barry'</span>, confirmed: <span class="pl-c1">true</span> } } }
|
54 | </code></pre>
|
55 | <pre><code class="lang-js">scour(data).get(<span class="pl-s">'users'</span>, <span class="pl-s">'1'</span>, <span class="pl-s">'name'</span>) <span class="pl-c">// => 'john'</span>
|
56 | </code></pre>
|
57 | <br>
|
58 | <h3 id="traversal">Traversal</h3>
|
59 | <p>Use <a href="#go">go()</a> to dig into the structure. It will return another <code>scour</code>
|
60 | wrapper scoped to that object.</p>
|
61 | <pre><code class="lang-js">data =
|
62 | { users:
|
63 | { admins:
|
64 | { bob: { logged_in: <span class="pl-c1">true</span> },
|
65 | sue: { logged_in: <span class="pl-c1">false</span> } } } }
|
66 | </code></pre>
|
67 | <pre><code class="lang-js">users = scour(data).go(<span class="pl-s">'users'</span>) <span class="pl-c">// => [scour (admins)]</span>
|
68 | admins = scour(data).go(<span class="pl-s">'users'</span>, <span class="pl-s">'admins'</span>) <span class="pl-c">// => [scour (bob, sue)]</span>
|
69 |
|
70 | admins.go(<span class="pl-s">'bob'</span>).get(<span class="pl-s">'logged_in'</span>) <span class="pl-c">// => true</span>
|
71 | </code></pre>
|
72 | <br>
|
73 | <h3 id="chaining">Chaining</h3>
|
74 | <p><code>scour()</code> provides a wrapper that can be used to chain methods. This is inspired by <a href="http://underscorejs.org/">Underscore</a> and <a href="http://lodash.com/">Lodash</a>.</p>
|
75 | <pre><code class="lang-js">scour(data)
|
76 | .go(<span class="pl-s">'users'</span>)
|
77 | .filter({ admin: <span class="pl-c1">true</span> })
|
78 | .value
|
79 | </code></pre>
|
80 | <br>
|
81 | <h3 id="immutable-modifications">Immutable modifications</h3>
|
82 | <p>Use <a href="#set">set()</a> to update values. Scout treats all data as immutable, so this
|
83 | doesn’t modify your original <code>data</code>, but gets you a new one with the
|
84 | modifications made.</p>
|
85 | <pre><code class="lang-js">data = scour(data)
|
86 | .set([<span class="pl-s">'users'</span>, <span class="pl-s">'1'</span>, <span class="pl-s">'updated_at'</span>], +<span class="pl-k">new</span> <span class="pl-c1">Date</span>())
|
87 | .value
|
88 |
|
89 | <span class="pl-c">// => { users:</span>
|
90 | <span class="pl-c">// { 1: { name: 'john', updated_at: 1450667171188 },</span>
|
91 | <span class="pl-c">// 2: { name: 'shane', confirmed: true },</span>
|
92 | <span class="pl-c">// 3: { name: 'barry', confirmed: true } } }</span>
|
93 | </code></pre>
|
94 | <br>
|
95 | <h3 id="advanced-traversing">Advanced traversing</h3>
|
96 | <p>Use <a href="#filter">filter()</a> to filter results with advanced querying.</p>
|
97 | <pre><code class="lang-js">users = scour(data).go(<span class="pl-s">'users'</span>)
|
98 |
|
99 | users
|
100 | .filter({ confirmed: <span class="pl-c1">true</span> })
|
101 | .at(<span class="hljs-number">0</span>)
|
102 | .get(<span class="pl-s">'name'</span>) <span class="pl-c">// => 'shane'</span>
|
103 | </code></pre>
|
104 | <br>
|
105 | <h3 id="models">Models</h3>
|
106 | <p>Use <a href="#use">use()</a> to add your own methods to certain keypaths. This makes them behave like models.<br>
|
107 | See <a href="extensions_example.html">a detailed example</a> to learn more.</p>
|
108 | <h5 class="file-heading" id="sample-data">Sample data</h5>
|
109 | <pre><code class="lang-js">data =
|
110 | { artists:
|
111 | { <span class="hljs-number">1</span>: { first_name: <span class="pl-s">'Louie'</span>, last_name: <span class="pl-s">'Armstrong'</span> },
|
112 | <span class="hljs-number">2</span>: { first_name: <span class="pl-s">'Miles'</span>, last_name: <span class="pl-s">'Davis'</span> } } }
|
113 | </code></pre>
|
114 | <h5 class="file-heading" id="your-models">Your models</h5>
|
115 | <pre><code class="lang-js">Root = {
|
116 | artists () { <span class="pl-k">return</span> <span class="pl-k">this</span>.go(<span class="pl-s">'artists'</span>) }
|
117 | }
|
118 |
|
119 | Artist = {
|
120 | fullname () {
|
121 | <span class="pl-k">return</span> <span class="pl-k">this</span>.get(<span class="pl-s">'first_name'</span>) + <span class="pl-s">' '</span> + <span class="pl-k">this</span>.get(<span class="pl-s">'last_name'</span>)
|
122 | }
|
123 | }
|
124 | </code></pre>
|
125 | <h5 class="file-heading" id="using-with-scour">Using with scour</h5>
|
126 | <pre><code class="lang-js">db = scour(data)
|
127 | .use({
|
128 | <span class="pl-s">''</span>: Root,
|
129 | <span class="pl-s">'artists.*'</span>: Artist
|
130 | })
|
131 |
|
132 | db.artists().find({ name: <span class="pl-s">'Miles'</span> }).fullname()
|
133 | <span class="pl-c">//=> 'Miles Davis'</span>
|
134 | </code></pre>
|
135 | <br>
|
136 | <h2 id="api">API</h2>
|
137 |
|
138 | <h3 id="scour">scour</h3>
|
139 | <blockquote>
|
140 | <p><code>scour(object)</code></p>
|
141 | </blockquote>
|
142 | <p>Returns a scour instance wrapping <code>object</code>.</p>
|
143 | <pre><code class="lang-js">scour(obj)
|
144 | </code></pre>
|
145 | <p>It can be called on any Object or Array. (In fact, it can be called on
|
146 | anything, but is only generally useful for Objects and Arrays.)</p>
|
147 | <pre><code class="lang-js">data = { menu: { visible: <span class="pl-c1">true</span>, position: <span class="pl-s">'left'</span> } }
|
148 | scour(data).get(<span class="pl-s">'menu.visible'</span>)
|
149 |
|
150 | list = [ { id: <span class="hljs-number">2</span> }, { id: <span class="hljs-number">5</span> }, { id: <span class="hljs-number">12</span> } ]
|
151 | scour(list).get(<span class="pl-s">'0.id'</span>)
|
152 | </code></pre>
|
153 | <p><strong>Chaining</strong>:
|
154 | You can use it to start method chains. In fact, the intended use is to keep
|
155 | your root <a href="#scour">scour</a> object around, and chain from this.</p>
|
156 | <pre><code class="lang-js">db = scour({ menu: { visible: <span class="pl-c1">true</span>, position: <span class="pl-s">'left'</span> } })
|
157 |
|
158 | <span class="pl-c">// Elsewhere:</span>
|
159 | menu = db.go(<span class="pl-s">'menu'</span>)
|
160 | menu.get(<span class="pl-s">'visible'</span>)
|
161 | </code></pre>
|
162 | <p><strong>Properties</strong>:
|
163 | It the <a href="#root">root</a>, <a href="#value">value</a> and <a href="#keypath">keypath</a> properties.</p>
|
164 | <pre><code class="lang-js">s = scour(obj)
|
165 | s.root <span class="pl-c">// => [scour object]</span>
|
166 | s.value <span class="pl-c">// => raw data (that is, `obj`)</span>
|
167 | s.keypath <span class="pl-c">// => string array</span>
|
168 | </code></pre>
|
169 | <p><strong>Accessing the value:</strong>
|
170 | You can access the raw data using <a href="#value">value</a>.</p>
|
171 | <pre><code class="lang-js">db = scour(data)
|
172 | db.value <span class="pl-c">// => same as `data`</span>
|
173 | db.go(<span class="pl-s">'users'</span>).value <span class="pl-c">// => same as `data.users`</span>
|
174 | </code></pre>
|
175 | <h2 id="chaining-methods">Chaining methods</h2>
|
176 | <p>These methods are used to traverse nested structures. All these
|
177 | methods return <a href="#scour">scour</a> instances, making them suitable for chaining.</p>
|
178 | <h3 id="go">go</h3>
|
179 | <blockquote>
|
180 | <p><code>go(keypath...)</code></p>
|
181 | </blockquote>
|
182 | <p>Navigates down to a given <code>keypath</code>. Always returns a <a href="#scour">scour</a> instance.</p>
|
183 | <pre><code class="lang-js">data =
|
184 | { users:
|
185 | { <span class="hljs-number">12</span>: { name: <span class="pl-s">'steve'</span>, last: <span class="pl-s">'jobs'</span> },
|
186 | <span class="hljs-number">23</span>: { name: <span class="pl-s">'bill'</span>, last: <span class="pl-s">'gates'</span> } } }
|
187 |
|
188 | scour(data).go(<span class="pl-s">'users'</span>) <span class="pl-c">// => [scour (users)]</span>
|
189 | scour(data).go(<span class="pl-s">'users'</span>, <span class="pl-s">'12'</span>) <span class="pl-c">// => [scour (name, last)]</span>
|
190 | scour(data).go(<span class="pl-s">'users'</span>, <span class="pl-s">'12'</span>).get(<span class="pl-s">'name'</span>) <span class="pl-c">// => 'steve'</span>
|
191 | </code></pre>
|
192 | <p><strong>Dot notation:</strong>
|
193 | Keypaths can be given in dot notation or as an array. These statements are
|
194 | equivalent.</p>
|
195 | <pre><code class="lang-js">scour(data).go(<span class="pl-s">'users.12'</span>)
|
196 | scour(data).go(<span class="pl-s">'users'</span>, <span class="pl-s">'12'</span>)
|
197 | scour(data).go([<span class="pl-s">'users'</span>, <span class="pl-s">'12'</span>])
|
198 | </code></pre>
|
199 | <p><strong>Non-objects:</strong>
|
200 | If you use it on a non-object or non-array value, it will still be
|
201 | returned as a <a href="#scour">scour</a> instance. This is not likely what you want; use
|
202 | <a href="#get">get()</a> instead.</p>
|
203 | <pre><code class="lang-js">attr = scour(data).go(<span class="pl-s">'users'</span>, <span class="pl-s">'12'</span>, <span class="pl-s">'name'</span>)
|
204 | attr <span class="pl-c">// => [scour object]</span>
|
205 | attr.value <span class="pl-c">// => 'steve'</span>
|
206 | attr.keypath <span class="pl-c">// => ['users', '12', 'name']</span>
|
207 | </code></pre>
|
208 | <h3 id="at">at</h3>
|
209 | <blockquote>
|
210 | <p><code>at(index)</code></p>
|
211 | </blockquote>
|
212 | <p>Returns the item at <code>index</code>. This differs from <code>go</code> as this searches by
|
213 | index, not by key.</p>
|
214 | <pre><code class="lang-js">users =
|
215 | { <span class="hljs-number">12</span>: { name: <span class="pl-s">'steve'</span> },
|
216 | <span class="hljs-number">23</span>: { name: <span class="pl-s">'bill'</span> } }
|
217 |
|
218 | scour(users).at(<span class="hljs-number">0</span>) <span class="pl-c">// => [scour { name: 'steve' }]</span>
|
219 | scour(users).get(<span class="hljs-number">12</span>) <span class="pl-c">// => [scour { name: 'steve' }]</span>
|
220 | </code></pre>
|
221 | <h3 id="filter">filter</h3>
|
222 | <blockquote>
|
223 | <p><code>filter(conditions)</code></p>
|
224 | </blockquote>
|
225 | <p>Sifts through the values and returns a set that matches given
|
226 | <code>conditions</code>. Supports simple objects, MongoDB-style
|
227 | queries, and functions.</p>
|
228 | <pre><code class="lang-js">scour(data).filter({ name: <span class="pl-s">'Moe'</span> })
|
229 | scour(data).filter({ name: { $<span class="pl-k">in</span>: [<span class="pl-s">'Larry'</span>, <span class="pl-s">'Curly'</span>] })
|
230 | scour(data).filter((item) => item.get(<span class="pl-s">'name'</span>) === <span class="pl-s">'Moe'</span>)
|
231 | </code></pre>
|
232 | <p><strong>Filter by object:</strong>
|
233 | If you pass an object as a condition, <code>filter()</code> will check if that object
|
234 | coincides with the objects in the collection.</p>
|
235 | <pre><code class="lang-js">scour(data).filter({ name: <span class="pl-s">'Moe'</span> })
|
236 | </code></pre>
|
237 | <p><strong>Filter by function:</strong>
|
238 | You may pass a function as a parameter. In this case, the <code>item</code> being
|
239 | passed to the callback will be a <a href="#scour">scour</a>-wrapped object. The result
|
240 | will also be a <a href="#scour">scour</a>-wrapped object, making it chainable.</p>
|
241 | <pre><code class="lang-js">scour(data)
|
242 | .filter((item, key) => +item.get(<span class="pl-s">'price'</span>) > <span class="hljs-number">200</span>)
|
243 | .sortBy(<span class="pl-s">'price'</span>)
|
244 | .first()
|
245 | </code></pre>
|
246 | <p><strong>Advanced queries:</strong>
|
247 | MongoDB-style queries are supported as provided by <a href="https://www.npmjs.com/package/sift">sift.js</a>. For
|
248 | reference, see <a href="https://docs.mongodb.org/manual/reference/operator/query/">MongoDB Query Operators</a>.</p>
|
249 | <pre><code class="lang-js">scour(products).filter({ price: { $gt: <span class="hljs-number">200</span> })
|
250 | scour(articles).filter({ published_at: { $not: <span class="pl-c1">null</span> }})
|
251 | </code></pre>
|
252 | <p><strong>Arrays or objects:</strong>
|
253 | Both arrays and array-like objects are supported. In this example below,
|
254 | an object will be used as the input.</p>
|
255 | <pre><code class="lang-js">devices =
|
256 | { <span class="hljs-number">1</span>: { id: <span class="hljs-number">1</span>, name: <span class="pl-s">'Phone'</span>, mobile: <span class="pl-c1">true</span> },
|
257 | <span class="hljs-number">2</span>: { id: <span class="hljs-number">2</span>, name: <span class="pl-s">'Tablet'</span>, mobile: <span class="pl-c1">true</span> },
|
258 | <span class="hljs-number">3</span>: { id: <span class="hljs-number">3</span>, name: <span class="pl-s">'Desktop'</span>, mobile: <span class="pl-c1">false</span> } }
|
259 |
|
260 | scour(devices).filter({ mobile: <span class="pl-c1">true</span> }).len()
|
261 | <span class="pl-c">// => 2</span>
|
262 | </code></pre>
|
263 | <p>Also see <a href="#scour-filter">scour.filter()</a> for the unwrapped version.</p>
|
264 | <h3 id="reject">reject</h3>
|
265 | <blockquote>
|
266 | <p><code>reject(conditions)</code></p>
|
267 | </blockquote>
|
268 | <p>Inverse of <a href="#filter">filter()</a> – see <code>filter()</code> documentation for details.</p>
|
269 | <h3 id="find">find</h3>
|
270 | <blockquote>
|
271 | <p><code>find(conditions)</code></p>
|
272 | </blockquote>
|
273 | <p>Returns the first value that matches <code>conditions</code>. Supports MongoDB-style
|
274 | queries. For reference, see <a href="https://docs.mongodb.org/manual/reference/operator/query/">MongoDB Query Operators</a>. Also
|
275 | see <a href="#filter">filter()</a>, as this is functionally-equivalent to the first result of
|
276 | <code>filter()</code>.</p>
|
277 | <pre><code class="lang-js">scour(data).find({ name: <span class="pl-s">'john'</span> })
|
278 | scour(data).find({ name: { $<span class="pl-k">in</span>: [<span class="pl-s">'moe'</span>, <span class="pl-s">'larry'</span>] })
|
279 | </code></pre>
|
280 | <h3 id="first">first</h3>
|
281 | <blockquote>
|
282 | <p><code>first()</code></p>
|
283 | </blockquote>
|
284 | <p>Returns the first result as a <a href="#scour">scour</a>-wrapped object. This is equivalent
|
285 | to <a href="#at">at(0)</a>.</p>
|
286 | <h3 id="last">last</h3>
|
287 | <blockquote>
|
288 | <p><code>last()</code></p>
|
289 | </blockquote>
|
290 | <p>Returns the first result as a <a href="#scour">scour</a>-wrapped object. This is equivalent
|
291 | to <code>at(len() - 1)</code>: see <a href="#at">at()</a> and <a href="#len">len()</a>.</p>
|
292 | <h3 id="sortby">sortBy</h3>
|
293 | <blockquote>
|
294 | <p><code>sortBy(condition)</code></p>
|
295 | </blockquote>
|
296 | <p>Sorts a collection. Returns a <a href="#scour">scour</a>-wrapped object suitable for
|
297 | chaining. Like other chainable methods, this works on arrays as well as
|
298 | objects.</p>
|
299 | <pre><code class="lang-js">data =
|
300 | { wilma: { name: <span class="pl-s">'Wilma'</span> },
|
301 | barney: { name: <span class="pl-s">'Barney'</span> },
|
302 | fred: { name: <span class="pl-s">'Fred'</span> } }
|
303 |
|
304 | scour(data).sortBy(<span class="pl-s">'name'</span>)
|
305 | </code></pre>
|
306 | <p><strong>Conditions:</strong>
|
307 | The given condition can be a string or a function. When it’s given as a
|
308 | function, the <code>item</code> being passed is a <a href="#scour">scour</a>-wrapped object, just like
|
309 | in <a href="#foreach">forEach()</a> (et al). These two examples below are
|
310 | functionally-equivalent.</p>
|
311 | <pre><code class="lang-js">scour(data).sortBy(<span class="pl-s">'name'</span>)
|
312 | scour(data).sortBy((item) => item.get(<span class="pl-s">'name'</span>))
|
313 | </code></pre>
|
314 | <h2 id="reading-methods">Reading methods</h2>
|
315 | <p>For retrieving data.</p>
|
316 | <h3 id="get">get</h3>
|
317 | <blockquote>
|
318 | <p><code>get(keypath...)</code></p>
|
319 | </blockquote>
|
320 | <p>Returns data in a given <code>keypath</code>.</p>
|
321 | <pre><code class="lang-js">data =
|
322 | { users:
|
323 | { <span class="hljs-number">12</span>: { name: <span class="pl-s">'steve'</span> },
|
324 | <span class="hljs-number">23</span>: { name: <span class="pl-s">'bill'</span> } } }
|
325 |
|
326 | scour(data).get(<span class="pl-s">'users'</span>) <span class="pl-c">// => same as data.users</span>
|
327 | scour(data).go(<span class="pl-s">'users'</span>).value <span class="pl-c">// => same as data.users</span>
|
328 | </code></pre>
|
329 | <p><strong>Dot notation:</strong>
|
330 | Like <a href="#go">go()</a>, the <code>keypath</code> can be given in dot notation.</p>
|
331 | <pre><code class="lang-js">scour(data).get(<span class="pl-s">'books.featured.name'</span>)
|
332 | scour(data).get(<span class="pl-s">'books'</span>, <span class="pl-s">'featured'</span>, <span class="pl-s">'name'</span>)
|
333 | </code></pre>
|
334 | <h3 id="len">len</h3>
|
335 | <blockquote>
|
336 | <p><code>len()</code></p>
|
337 | </blockquote>
|
338 | <p>Returns the length of the object or array. For objects, it returns the
|
339 | number of keys.</p>
|
340 | <pre><code class="lang-js">users =
|
341 | { <span class="hljs-number">12</span>: { name: <span class="pl-s">'steve'</span> },
|
342 | <span class="hljs-number">23</span>: { name: <span class="pl-s">'bill'</span> } }
|
343 |
|
344 | names = scour(users).len() <span class="pl-c">// => 2</span>
|
345 | </code></pre>
|
346 | <h3 id="toarray">toArray</h3>
|
347 | <blockquote>
|
348 | <p><code>toArray()</code></p>
|
349 | </blockquote>
|
350 | <p>Returns an array. If the the value is an object, it returns the values of
|
351 | that object. If the value is an array, it returns it as is. Also aliased
|
352 | as <code>values()</code>.</p>
|
353 | <pre><code class="lang-js">users =
|
354 | { <span class="hljs-number">12</span>: { name: <span class="pl-s">'steve'</span> },
|
355 | <span class="hljs-number">23</span>: { name: <span class="pl-s">'bill'</span> } }
|
356 |
|
357 | names = scour(users).toArray()
|
358 | <span class="pl-c">// => [ {name: 'steve'}, {name: 'bill'} ]</span>
|
359 | </code></pre>
|
360 | <h3 id="keys">keys</h3>
|
361 | <blockquote>
|
362 | <p><code>keys()</code></p>
|
363 | </blockquote>
|
364 | <p>Returns keys. If the value is an array, this returns the array’s indices.
|
365 | Also see <a href="#toarray">toArray()</a> to retrieve the values instead.</p>
|
366 | <h2 id="writing-methods">Writing methods</h2>
|
367 | <p>These are methods for modifying an object/array tree immutably.
|
368 | Note that all these functions are immutable–it will not modify existing
|
369 | data, but rather spawn new objects with the modifications done on them.</p>
|
370 | <h3 id="set">set</h3>
|
371 | <blockquote>
|
372 | <p><code>set(keypath, value)</code></p>
|
373 | </blockquote>
|
374 | <p>Sets values immutably. Returns a copy of the same object (<a href="#scour">scour</a>-wrapped)
|
375 | with the modifications applied.</p>
|
376 | <pre><code class="lang-js">data = { bob: { name: <span class="pl-s">'Bob'</span> } }
|
377 | db = scour(data)
|
378 | db.set([ <span class="pl-s">'bob'</span>, <span class="pl-s">'name'</span> ], <span class="pl-s">'Robert'</span>)
|
379 | <span class="pl-c">// db.value == { bob: { name: 'Robert' } }</span>
|
380 | </code></pre>
|
381 | <p><strong>Immutability:</strong>
|
382 | This is an immutable function, and will return a new object. It won’t
|
383 | modify your original object.</p>
|
384 | <pre><code class="lang-js">profile = scour({ name: <span class="pl-s">'John'</span> })
|
385 | profile2 = profile.set(<span class="pl-s">'email'</span>, <span class="pl-s">'john@gmail.com'</span>)
|
386 |
|
387 | profile.value <span class="pl-c">// => { name: 'John' }</span>
|
388 | profile2.value <span class="pl-c">// => { name: 'John', email: 'john@gmail.com' }</span>
|
389 | </code></pre>
|
390 | <p><strong>Using within a scope:</strong>
|
391 | Be aware that using all writing methods (<a href="#set">set()</a>, <a href="#del">del()</a>, <a href="#extend">extend()</a>) on
|
392 | scoped objects (ie, made with <a href="#go">go()</a>) will spawn a new <a href="#root">root</a> object. If
|
393 | you’re keeping a reference to the root object, you’ll need to update it
|
394 | accordingly.</p>
|
395 | <pre><code class="lang-js">db = scour(data)
|
396 | book = db.go(<span class="pl-s">'book'</span>)
|
397 | book.root === db <span class="pl-c">// correct so far</span>
|
398 |
|
399 | book = book.set(<span class="pl-s">'title'</span>, <span class="pl-s">'IQ84'</span>)
|
400 | book = book.del(<span class="pl-s">'sale_price'</span>)
|
401 | book.root !== db <span class="pl-c">// `root` has been updated</span>
|
402 | </code></pre>
|
403 | <p><strong>Dot notation:</strong>
|
404 | Like <a href="#go">go()</a> and <a href="#get">get()</a>, the keypath can be given in dot notation or an
|
405 | array.</p>
|
406 | <pre><code class="lang-js">scour(data).set(<span class="pl-s">'menu.left.visible'</span>, <span class="pl-c1">true</span>)
|
407 | scour(data).set([<span class="pl-s">'menu'</span>, <span class="pl-s">'left'</span>, <span class="pl-s">'visible'</span>], <span class="pl-c1">true</span>)
|
408 | </code></pre>
|
409 | <h3 id="del">del</h3>
|
410 | <blockquote>
|
411 | <p><code>del(keypath)</code></p>
|
412 | </blockquote>
|
413 | <p>Deletes values immutably. Returns a copy of the same object
|
414 | (<a href="#scour">scour</a>-wrapped) with the modifications applied.</p>
|
415 | <p>Like <a href="#set">set()</a>, the keypath can be given in dot notation or an
|
416 | array.</p>
|
417 | <pre><code class="lang-js">scour(data).del(<span class="pl-s">'menu.left.visible'</span>)
|
418 | scour(data).del([<span class="pl-s">'menu'</span>, <span class="pl-s">'left'</span>, <span class="pl-s">'visible'</span>])
|
419 | </code></pre>
|
420 | <p>See <a href="#set">set()</a> for more information on working with immutables.</p>
|
421 | <h3 id="extend">extend</h3>
|
422 | <blockquote>
|
423 | <p><code>extend(objects...)</code></p>
|
424 | </blockquote>
|
425 | <p>Extends the data with more values. Returns a <a href="#scour">scour</a>-wrapped object. Only
|
426 | supports objects; arrays and non-objects will return undefined. Just like
|
427 | <a href="https://devdocs.io/javascript/global_objects/object/assign">Object.assign</a>, you may pass multiple objects to the parameters.</p>
|
428 | <pre><code class="lang-js">data = { a: <span class="hljs-number">1</span>, b: <span class="hljs-number">2</span> }
|
429 | data2 = scour(data).extend({ c: <span class="hljs-number">3</span> })
|
430 | </code></pre>
|
431 | <pre><code class="lang-js">data2 <span class="pl-c">// => [scour { a: 1, b: 2, c: 3 }]</span>
|
432 | data2.value <span class="pl-c">// => { a: 1, b: 2, c: 3 }</span>
|
433 | </code></pre>
|
434 | <p>See <a href="#set">set()</a> for more information on working with immutables.</p>
|
435 | <h2 id="utility-methods">Utility methods</h2>
|
436 | <p>For stuff.</p>
|
437 | <h3 id="use">use</h3>
|
438 | <blockquote>
|
439 | <p><code>use(extensions)</code></p>
|
440 | </blockquote>
|
441 | <p>Extends functionality for certain keypaths with custom methods.
|
442 | See <a href="extensions_example.html">Extensions example</a> for examples.</p>
|
443 | <pre><code class="lang-js">data =
|
444 | { users:
|
445 | { <span class="hljs-number">12</span>: { name: <span class="pl-s">'steve'</span>, surname: <span class="pl-s">'jobs'</span> },
|
446 | <span class="hljs-number">23</span>: { name: <span class="pl-s">'bill'</span>, surname: <span class="pl-s">'gates'</span> } } }
|
447 |
|
448 | extensions = {
|
449 | <span class="pl-s">'users.*'</span>: {
|
450 | fullname () {
|
451 | <span class="pl-k">return</span> <span class="pl-k">this</span>.get(<span class="pl-s">'name'</span>) + <span class="pl-s">' '</span> + <span class="pl-k">this</span>.get(<span class="pl-s">'surname'</span>)
|
452 | }
|
453 | }
|
454 | }
|
455 |
|
456 | scour(data)
|
457 | .use(extensions)
|
458 | .get(<span class="pl-s">'users'</span>, <span class="hljs-number">12</span>)
|
459 | .fullname() <span class="pl-c">// => 'bill gates'</span>
|
460 | </code></pre>
|
461 | <p><strong>Extensions format:</strong>
|
462 | The parameter <code>extension</code> is an object, with keys being keypath globs, and
|
463 | values being properties to be extended.</p>
|
464 | <pre><code class="lang-js">.use({
|
465 | <span class="pl-s">'books.*'</span>: { ... },
|
466 | <span class="pl-s">'authors.*'</span>: { ... },
|
467 | <span class="pl-s">'publishers.*'</span>: { ... }
|
468 | })
|
469 | </code></pre>
|
470 | <p><strong>Extending root:</strong>
|
471 | To bind properties to the root method, use an empty string as the keypath.</p>
|
472 | <pre><code class="lang-js">.use({
|
473 | <span class="pl-s">''</span>: {
|
474 | users() { <span class="pl-k">return</span> <span class="pl-k">this</span>.go(<span class="pl-s">'users'</span>) },
|
475 | authors() { <span class="pl-k">return</span> <span class="pl-k">this</span>.go(<span class="pl-s">'authors'</span>) }
|
476 | }
|
477 | })
|
478 | </code></pre>
|
479 | <p><strong>Keypath filtering:</strong>
|
480 | You can use glob-like <code>*</code> and <code>**</code> to match parts of a keypath. A <code>*</code> will
|
481 | match any one segment, and <code>**</code> will match one or many segments. Here are
|
482 | some examples:</p>
|
483 | <ul>
|
484 | <li><code>users.*</code> - will match <code>users.1</code>, but not <code>users.1.photos</code></li>
|
485 | <li><code>users.**</code> - will match <code>users.1.photos</code></li>
|
486 | <li><code>users.*.photos</code> - will match <code>users.1.photos</code></li>
|
487 | <li><code>**</code> will match anything</li>
|
488 | </ul>
|
489 | <p><strong>When using outside root:</strong>
|
490 | Any extensions in a scoped object (ie, made with <a href="#go">go()</a>) will be used relative
|
491 | to it. For instance, if you define an extension to <code>admins.*</code> inside
|
492 | <code>.go('users')</code>, it will affect `users.</p>
|
493 | <pre><code class="lang-js">data = { users: { john: { } }
|
494 | db = scour(data)
|
495 |
|
496 | users = db.go(<span class="pl-s">'users'</span>)
|
497 | .use({ <span class="pl-s">'*'</span>: { hasName () { <span class="pl-k">return</span> !!<span class="pl-k">this</span>.get(<span class="pl-s">'name'</span>) } })
|
498 |
|
499 | users.go(<span class="pl-s">'john'</span>).hasName() <span class="pl-c">// works</span>
|
500 | </code></pre>
|
501 | <p>While this is supported, it is <em>not</em> recommended: these extensions will not
|
502 | propagate back to the root, and any objects taken from the root will not
|
503 | have those extensions applied to them.</p>
|
504 | <pre><code class="lang-js">users.go(<span class="pl-s">'john'</span>).hasName() <span class="pl-c">// works</span>
|
505 | db.go(<span class="pl-s">'users.john'</span>).hasName() <span class="pl-c">// doesn't work</span>
|
506 | </code></pre>
|
507 | <h3 id="tojson">toJSON</h3>
|
508 | <blockquote>
|
509 | <p><code>toJSON()</code></p>
|
510 | </blockquote>
|
511 | <p>Returns the value for serialization. This allows <code>JSON.stringify()</code> to
|
512 | work with <code>scour</code>-wrapped objects. The name of this method is a bit
|
513 | confusing, as it doesn’t actually return a JSON string — but I’m afraid
|
514 | that it’s the way that the JavaScript API for <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON%28%29_behavior">JSON.stringify</a> works.</p>
|
515 | <h2 id="iteration-methods">Iteration methods</h2>
|
516 | <p>These methods are generally useful for collections. These
|
517 | methods can work with either arrays or array-like objects, such as
|
518 | below.</p>
|
519 | <pre><code class="lang-js">subjects =
|
520 | { <span class="hljs-number">1</span>: { id: <span class="hljs-number">1</span>, title: <span class="pl-s">'Math'</span>, level: <span class="hljs-number">101</span> },
|
521 | <span class="hljs-number">2</span>: { id: <span class="hljs-number">2</span>, title: <span class="pl-s">'Science'</span>, level: <span class="hljs-number">103</span> },
|
522 | <span class="hljs-number">3</span>: { id: <span class="hljs-number">3</span>, title: <span class="pl-s">'History'</span>, level: <span class="hljs-number">102</span> } }
|
523 | </code></pre>
|
524 | <p><strong>Values:</strong>
|
525 | For all these functions, The items passed onto the callbacks <em>is</em> a
|
526 | <a href="#scour">scour</a>-wrapped object. Use <code>item.value</code> or <code>this</code> to access the raw
|
527 | values.</p>
|
528 | <pre><code class="lang-js">scour(subjects).forEach((subject, key) => {
|
529 | <span class="pl-c1">console</span>.log(subject.get(<span class="pl-s">'title'</span>))
|
530 | })
|
531 | </code></pre>
|
532 | <p><strong>Return values:</strong>
|
533 | For methods that return values (such as <a href="#map">map()</a>, the returned results <em>is
|
534 | not</em> a <a href="#scour">scour</a>-wrapped object, and isn’t suitable for chaining.</p>
|
535 | <pre><code class="lang-js">scour(subjects).map((subject, key) => {
|
536 | <span class="pl-k">return</span> subject.get(<span class="pl-s">'title'</span>) + <span class="pl-s">' '</span> + subject.get(<span class="pl-s">'level'</span>)
|
537 | })
|
538 | <span class="pl-c">// => [ 'Math 101', 'Science 103', 'History 102' ]</span>
|
539 | </code></pre>
|
540 | <h3 id="foreach">forEach</h3>
|
541 | <blockquote>
|
542 | <p><code>forEach(function(item, key, index))</code></p>
|
543 | </blockquote>
|
544 | <p>Loops through each item. Supports both arrays and objects.
|
545 | The rules specified in <a href="#iteration-methods">Iteration methods</a> apply.</p>
|
546 | <pre><code class="lang-js">users =
|
547 | { <span class="hljs-number">12</span>: { name: <span class="pl-s">'steve'</span> },
|
548 | <span class="hljs-number">23</span>: { name: <span class="pl-s">'bill'</span> } }
|
549 |
|
550 | scour(users).each((user, key) => {
|
551 | <span class="pl-c1">console</span>.log(user.get(<span class="pl-s">'name'</span>))
|
552 | })
|
553 | </code></pre>
|
554 | <p>The values passed onto the function are:</p>
|
555 | <ul>
|
556 | <li><code>item</code> - the value; always a scour object.</li>
|
557 | <li><code>key</code> - the key.</li>
|
558 | <li><code>index</code> - the index.</li>
|
559 | </ul>
|
560 | <h3 id="each">each</h3>
|
561 | <blockquote>
|
562 | <p><code>each(fn)</code></p>
|
563 | </blockquote>
|
564 | <p>Alias for <a href="#foreach">forEach</a>.</p>
|
565 | <h3 id="map">map</h3>
|
566 | <blockquote>
|
567 | <p><code>map(function(item, key))</code></p>
|
568 | </blockquote>
|
569 | <p>Loops through each item and returns an array based on the iterator’s
|
570 | return values. Supports both arrays and objects.
|
571 | The rules specified in <a href="#iteration-methods">Iteration methods</a> apply.</p>
|
572 | <pre><code class="lang-js">users =
|
573 | { <span class="hljs-number">12</span>: { name: <span class="pl-s">'Steve'</span> },
|
574 | <span class="hljs-number">23</span>: { name: <span class="pl-s">'Bill'</span> } }
|
575 |
|
576 | names = scour(users).map((user, key) => user.get(<span class="pl-s">'name'</span>))
|
577 | <span class="pl-c">// => [ 'Steve', 'Bill' ]</span>
|
578 | </code></pre>
|
579 | <h3 id="mapobject">mapObject</h3>
|
580 | <blockquote>
|
581 | <p><code>mapObject(function(val, key))</code></p>
|
582 | </blockquote>
|
583 | <p>Creates a new <code>Object</code> with with the results of calling a provided function
|
584 | on every element in this array. Works like <a href="http://devdocs.io/javascript/global_objects/array/map">Array#map</a>, but also works on
|
585 | objects as well as arrays, and it returns an object instead.
|
586 | The rules specified in <a href="#iteration-methods">Iteration methods</a> apply.</p>
|
587 | <p>See <a href="#scour.mapobject">scour.mapObject()</a> for details and the non-wrapped version.</p>
|
588 | <h3 id="indexedmap">indexedMap</h3>
|
589 | <blockquote>
|
590 | <p><code>indexedMap(function(val, key))</code></p>
|
591 | </blockquote>
|
592 | <p>Creates a new <code>Object</code> with with the results of calling a provided function
|
593 | returning the keys and values for the new object.
|
594 | The rules specified in <a href="#iteration-methods">Iteration methods</a> apply.</p>
|
595 | <p>See <a href="#scour.indexedmap">scour.indexedMap()</a> for details and the non-wrapped version.</p>
|
596 | <h2 id="attributes">Attributes</h2>
|
597 | <p>These attributes are available to <a href="#scour">scour</a> instances.</p>
|
598 | <h3 id="value">value</h3>
|
599 | <blockquote>
|
600 | <p><code>value</code></p>
|
601 | </blockquote>
|
602 | <p>The raw value being wrapped. You can use this to terminate a chained call.</p>
|
603 | <pre><code class="lang-js">users =
|
604 | [ { name: <span class="pl-s">'john'</span>, admin: <span class="pl-c1">true</span> },
|
605 | { name: <span class="pl-s">'kyle'</span>, admin: <span class="pl-c1">false</span> } ]
|
606 |
|
607 | scour(users)
|
608 | .filter({ admin: <span class="pl-c1">true</span> })
|
609 | .value
|
610 | <span class="pl-c">// => [ { name: 'john', admin: true } ]</span>
|
611 | </code></pre>
|
612 | <h3 id="root">root</h3>
|
613 | <blockquote>
|
614 | <p><code>root</code></p>
|
615 | </blockquote>
|
616 | <p>A reference to the root <a href="#scour">scour</a> instance.
|
617 | Everytime you traverse using <a href="#go">go()</a>, a new <a href="#scour">scour</a> object is spawned that’s
|
618 | scoped to a keypath. Each of these <a href="#scour">scour</a> objects have a <code>root</code> attribute
|
619 | that’s a reference to the top-level <a href="#scour">scour</a> object.</p>
|
620 | <pre><code class="lang-js">db = scour(...)
|
621 |
|
622 | photos = db.go(<span class="pl-s">'photos'</span>)
|
623 | photos.root <span class="pl-c">// => same as `db`</span>
|
624 | </code></pre>
|
625 | <p>This allows you to return to the root when needed.</p>
|
626 | <pre><code class="lang-js">db = scour(...)
|
627 | artist = db.go(<span class="pl-s">'artists'</span>, <span class="pl-s">'9328'</span>)
|
628 | artist.root.go(<span class="pl-s">'albums'</span>).find({ artist_id: artist.get(<span class="pl-s">'id'</span>) })
|
629 | </code></pre>
|
630 | <h3 id="keypath">keypath</h3>
|
631 | <blockquote>
|
632 | <p><code>keypath</code></p>
|
633 | </blockquote>
|
634 | <p>An array of strings representing each step in how deep the current scope is
|
635 | relative to the root. Each time you traverse using <a href="#go">go()</a>, a new <a href="#scour">scour</a>
|
636 | object is spawned.</p>
|
637 | <pre><code class="lang-js">db = scour(...)
|
638 |
|
639 | users = db.go(<span class="pl-s">'users'</span>)
|
640 | users.keypath <span class="pl-c">// => ['users']</span>
|
641 |
|
642 | admins = users.go(<span class="pl-s">'admins'</span>)
|
643 | admins.keypath <span class="pl-c">// => ['users', 'admins']</span>
|
644 |
|
645 | user = admins.go(<span class="pl-s">'23'</span>)
|
646 | user.keypath <span class="pl-c">// => ['users', 'admins', '23']</span>
|
647 | </code></pre>
|
648 | <h2 id="utility-functions">Utility functions</h2>
|
649 | <p>These are utilities that don’t need a wrapped object.</p>
|
650 | <h3 id="scour.set">scour.set</h3>
|
651 | <blockquote>
|
652 | <p><code>scour.set(object, keypath, value)</code></p>
|
653 | </blockquote>
|
654 | <p>Sets a <code>keypath</code> into an <code>object</code> immutably.</p>
|
655 | <pre><code class="lang-js">data = { users: { bob: { name: <span class="pl-s">'john'</span> } } }
|
656 |
|
657 | result = set(data, [<span class="pl-s">'users'</span>, <span class="pl-s">'bob'</span>, <span class="pl-s">'name'</span>], <span class="pl-s">'robert'</span>)
|
658 | <span class="pl-c">// => { users: { bob: { name: 'robert' } } }</span>
|
659 | </code></pre>
|
660 | <p>This is also available as <code>require('scourjs/utilities/set')</code>.</p>
|
661 | <h3 id="scour.del">scour.del</h3>
|
662 | <blockquote>
|
663 | <p><code>scour.del(object, keypath)</code></p>
|
664 | </blockquote>
|
665 | <p>Deletes a <code>keypath</code> from an <code>object</code> immutably.</p>
|
666 | <pre><code class="lang-js">data = { users: { bob: { name: <span class="pl-s">'robert'</span> } } }
|
667 | result = del(data, [<span class="pl-s">'users'</span>, <span class="pl-s">'bob'</span>, <span class="pl-s">'name'</span>])
|
668 |
|
669 | <span class="pl-c">// => { users: { bob: {} } }</span>
|
670 | </code></pre>
|
671 | <p>This is also available as <code>require('scourjs/utilities/del')</code>.</p>
|
672 | <h3 id="scour.each">scour.each</h3>
|
673 | <blockquote>
|
674 | <p><code>scour.each(iterable, fn)</code></p>
|
675 | </blockquote>
|
676 | <p>Iterates through <code>iterable</code>, either an object or an array. This is an
|
677 | implementation of <a href="http://devdocs.io/javascript/global_objects/array/foreach">Array#forEach</a> that also works for objects. The callback
|
678 | <code>fn</code> will be invoked with two parameters: <code>currentValue</code> and <code>key</code>, just
|
679 | like <code>Array#forEach</code>.</p>
|
680 | <p>This is also available as <code>require('scourjs/utilities/each')</code>.</p>
|
681 | <h3 id="scour.map">scour.map</h3>
|
682 | <blockquote>
|
683 | <p><code>scour.map(iterable, fn)</code></p>
|
684 | </blockquote>
|
685 | <p>Creates a new <code>Array</code> with with the results of calling a provided function
|
686 | on every element in this array. Works like <a href="http://devdocs.io/javascript/global_objects/array/map">Array#map</a>, but also works on
|
687 | objects as well as arrays.</p>
|
688 | <p>The callback <code>fn</code> will be invoked with two parameters: <code>currentValue</code> and
|
689 | <code>key</code>, just like <a href="http://devdocs.io/javascript/global_objects/array/map">Array#map</a>.</p>
|
690 | <p>This is also available as <code>require('scourjs/utilities/map')</code>.</p>
|
691 | <h3 id="scour.mapobject">scour.mapObject</h3>
|
692 | <blockquote>
|
693 | <p><code>scour.mapObject(iterable, fn)</code></p>
|
694 | </blockquote>
|
695 | <p>Creates a new <code>Object</code> with with the results of calling a provided function
|
696 | on every element in this array. Works like <a href="http://devdocs.io/javascript/global_objects/array/map">Array#map</a>, but also works on
|
697 | objects as well as arrays, and it returns an object instead.</p>
|
698 | <p>The callback <code>fn</code> will be invoked with two parameters: <code>currentValue</code> and
|
699 | <code>key</code>, just like <a href="http://devdocs.io/javascript/global_objects/array/map">Array#map</a>.</p>
|
700 | <pre><code class="lang-js">object = { a: <span class="hljs-number">20</span>, b: <span class="hljs-number">30</span>, c: <span class="hljs-number">40</span> }
|
701 | result = scour.mapObject(object, (val, key) => {
|
702 | <span class="pl-k">return</span> <span class="pl-s">'$'</span> + val + <span class="pl-s">'.00'</span>
|
703 | })
|
704 |
|
705 | <span class="pl-c">// => { a: '$20.00', b: '$30.00', c: '$40.00' }</span>
|
706 | </code></pre>
|
707 | <p>This is also available as <code>require('scourjs/utilities/map_object')</code>.</p>
|
708 | <h3 id="scour.indexedmap">scour.indexedMap</h3>
|
709 | <blockquote>
|
710 | <p><code>scour.indexedMap(iterable, fn)</code></p>
|
711 | </blockquote>
|
712 | <p>Creates a new <code>Object</code> with with the results of calling a provided function
|
713 | returning the keys and values for the new object.</p>
|
714 | <p>The callback <code>fn</code> will be invoked with two parameters: <code>currentValue</code> and
|
715 | <code>key</code>, just like <a href="http://devdocs.io/javascript/global_objects/array/map">Array#map</a>.</p>
|
716 | <p>The callback <code>fn</code> should return an array with two elements: with <code>result[0]</code>
|
717 | being the key, and <code>result[1]</code> being the value. These are what the new
|
718 | object will be constructed with.</p>
|
719 | <p>The <code>iterable</code> parameter can be an object or an array. This works like
|
720 | <code>Array#map</code>, but also works on objects as well as arrays.</p>
|
721 | <pre><code class="lang-js">list = [<span class="pl-s">'Fred'</span>, <span class="pl-s">'Barney'</span>, <span class="pl-s">'Wilma'</span>]
|
722 |
|
723 | object = scour.indexedMap(list, (val, key) => {
|
724 | <span class="pl-k">var</span> newkey = val.substr(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>)
|
725 | <span class="pl-k">return</span> [ newkey, val ]
|
726 | })
|
727 |
|
728 | <span class="pl-c">// => { f: 'Fred', b: 'Barney', w: 'Wilma' }</span>
|
729 | </code></pre>
|
730 | <p>This is also available as <code>require('scourjs/utilities/indexed_map')</code>.</p>
|
731 | <h3 id="scour.filter">scour.filter</h3>
|
732 | <blockquote>
|
733 | <p><code>scour.filter(iterable, function(val, key), [isArray])</code></p>
|
734 | </blockquote>
|
735 | <p>Creates a new Array or Object with all elements that pass the test
|
736 | implemented by the provided function.</p>
|
737 | <p>Works like <a href="http://devdocs.io/javascript/global_objects/array/filter">Array#filter</a>, but will return an object if an object is also passed.</p>
|
738 | <p>The optional <code>isArray</code> argument, when passed <code>true</code>, will always make this
|
739 | return an <code>Array</code>. If <code>false</code>, it will always be an <code>Object</code>. Leave it
|
740 | <code>undefined</code> for the default behavior.</p>
|
741 | <p>This is also available as <code>require('scourjs/utilities/filter')</code>.</p>
|
742 |
|
743 | <h2 id="thanks">Thanks</h2>
|
744 | <p><strong>scour</strong> © 2015+, Rico Sta. Cruz. Released under the <a href="http://mit-license.org/">MIT</a> License.<br>
|
745 | Authored and maintained by Rico Sta. Cruz with help from contributors (<a href="http://github.com/rstacruz/scour/contributors">list</a>).</p>
|
746 | <blockquote>
|
747 | <p><a href="http://ricostacruz.com">ricostacruz.com</a>  · 
|
748 | GitHub <a href="https://github.com/rstacruz">@rstacruz</a>  · 
|
749 | Twitter <a href="https://twitter.com/rstacruz">@rstacruz</a></p>
|
750 | </blockquote>
|
751 |
|
752 | </div>
|
753 | <div class="footer-nav">
|
754 | <div class="right"><a href="HISTORY.html"><span class="label">Next: </span><span class="title">Changelog</span></a></div>
|
755 | </div>
|
756 | </div>
|
757 | <div class="menu toc-menu">
|
758 | <li class="menu-item -level-0 -parent">
|
759 | <ul class="submenu">
|
760 | <li class="menu-item -level-1"><a href="index.html" class="link title -active link-index">scour.js</a>
|
761 | </li>
|
762 | <li class="menu-item -level-1"><a href="#install" class="link title link-install">Install</a>
|
763 | </li>
|
764 | <li class="menu-item -level-1 -parent"><a href="#features" class="link title link-features">Features</a>
|
765 | <ul class="submenu">
|
766 | <li class="menu-item -level-2"><a href="#traversal" class="link title link-traversal">Traversal</a>
|
767 | </li>
|
768 | <li class="menu-item -level-2"><a href="#chaining" class="link title link-chaining">Chaining</a>
|
769 | </li>
|
770 | <li class="menu-item -level-2"><a href="#immutable-modifications" class="link title link-immutable-modifications">Immutable modifications</a>
|
771 | </li>
|
772 | <li class="menu-item -level-2"><a href="#advanced-traversing" class="link title link-advanced-traversing">Advanced traversing</a>
|
773 | </li>
|
774 | <li class="menu-item -level-2"><a href="#models" class="link title link-models">Models</a>
|
775 | </li>
|
776 | </ul>
|
777 | </li>
|
778 | <li class="menu-item -level-1 -parent"><a href="#api" class="link title link-api">API</a>
|
779 | <ul class="submenu">
|
780 | <li class="menu-item -level-2"><a href="#scour" class="link title link-scour">scour</a>
|
781 | </li>
|
782 | </ul>
|
783 | </li>
|
784 | <li class="menu-item -level-1 -parent"><a href="#chaining-methods" class="link title link-chaining-methods">Chaining methods</a>
|
785 | <ul class="submenu">
|
786 | <li class="menu-item -level-2"><a href="#go" class="link title link-go">go</a>
|
787 | </li>
|
788 | <li class="menu-item -level-2"><a href="#at" class="link title link-at">at</a>
|
789 | </li>
|
790 | <li class="menu-item -level-2"><a href="#filter" class="link title link-filter">filter</a>
|
791 | </li>
|
792 | <li class="menu-item -level-2"><a href="#reject" class="link title link-reject">reject</a>
|
793 | </li>
|
794 | <li class="menu-item -level-2"><a href="#find" class="link title link-find">find</a>
|
795 | </li>
|
796 | <li class="menu-item -level-2"><a href="#first" class="link title link-first">first</a>
|
797 | </li>
|
798 | <li class="menu-item -level-2"><a href="#last" class="link title link-last">last</a>
|
799 | </li>
|
800 | <li class="menu-item -level-2"><a href="#sortby" class="link title link-sortby">sortBy</a>
|
801 | </li>
|
802 | </ul>
|
803 | </li>
|
804 | <li class="menu-item -level-1 -parent"><a href="#reading-methods" class="link title link-reading-methods">Reading methods</a>
|
805 | <ul class="submenu">
|
806 | <li class="menu-item -level-2"><a href="#get" class="link title link-get">get</a>
|
807 | </li>
|
808 | <li class="menu-item -level-2"><a href="#len" class="link title link-len">len</a>
|
809 | </li>
|
810 | <li class="menu-item -level-2"><a href="#toarray" class="link title link-toarray">toArray</a>
|
811 | </li>
|
812 | <li class="menu-item -level-2"><a href="#keys" class="link title link-keys">keys</a>
|
813 | </li>
|
814 | </ul>
|
815 | </li>
|
816 | <li class="menu-item -level-1 -parent"><a href="#writing-methods" class="link title link-writing-methods">Writing methods</a>
|
817 | <ul class="submenu">
|
818 | <li class="menu-item -level-2"><a href="#set" class="link title link-set">set</a>
|
819 | </li>
|
820 | <li class="menu-item -level-2"><a href="#del" class="link title link-del">del</a>
|
821 | </li>
|
822 | <li class="menu-item -level-2"><a href="#extend" class="link title link-extend">extend</a>
|
823 | </li>
|
824 | </ul>
|
825 | </li>
|
826 | <li class="menu-item -level-1 -parent"><a href="#utility-methods" class="link title link-utility-methods">Utility methods</a>
|
827 | <ul class="submenu">
|
828 | <li class="menu-item -level-2"><a href="#use" class="link title link-use">use</a>
|
829 | </li>
|
830 | <li class="menu-item -level-2"><a href="#tojson" class="link title link-tojson">toJSON</a>
|
831 | </li>
|
832 | </ul>
|
833 | </li>
|
834 | <li class="menu-item -level-1 -parent"><a href="#iteration-methods" class="link title link-iteration-methods">Iteration methods</a>
|
835 | <ul class="submenu">
|
836 | <li class="menu-item -level-2"><a href="#foreach" class="link title link-foreach">forEach</a>
|
837 | </li>
|
838 | <li class="menu-item -level-2"><a href="#each" class="link title link-each">each</a>
|
839 | </li>
|
840 | <li class="menu-item -level-2"><a href="#map" class="link title link-map">map</a>
|
841 | </li>
|
842 | <li class="menu-item -level-2"><a href="#mapobject" class="link title link-mapobject">mapObject</a>
|
843 | </li>
|
844 | <li class="menu-item -level-2"><a href="#indexedmap" class="link title link-indexedmap">indexedMap</a>
|
845 | </li>
|
846 | </ul>
|
847 | </li>
|
848 | <li class="menu-item -level-1 -parent"><a href="#attributes" class="link title link-attributes">Attributes</a>
|
849 | <ul class="submenu">
|
850 | <li class="menu-item -level-2"><a href="#value" class="link title link-value">value</a>
|
851 | </li>
|
852 | <li class="menu-item -level-2"><a href="#root" class="link title link-root">root</a>
|
853 | </li>
|
854 | <li class="menu-item -level-2"><a href="#keypath" class="link title link-keypath">keypath</a>
|
855 | </li>
|
856 | </ul>
|
857 | </li>
|
858 | <li class="menu-item -level-1 -parent"><a href="#utility-functions" class="link title link-utility-functions">Utility functions</a>
|
859 | <ul class="submenu">
|
860 | <li class="menu-item -level-2"><a href="#scour.set" class="link title link-scour.set">scour.set</a>
|
861 | </li>
|
862 | <li class="menu-item -level-2"><a href="#scour.del" class="link title link-scour.del">scour.del</a>
|
863 | </li>
|
864 | <li class="menu-item -level-2"><a href="#scour.each" class="link title link-scour.each">scour.each</a>
|
865 | </li>
|
866 | <li class="menu-item -level-2"><a href="#scour.map" class="link title link-scour.map">scour.map</a>
|
867 | </li>
|
868 | <li class="menu-item -level-2"><a href="#scour.mapobject" class="link title link-scour.mapobject">scour.mapObject</a>
|
869 | </li>
|
870 | <li class="menu-item -level-2"><a href="#scour.indexedmap" class="link title link-scour.indexedmap">scour.indexedMap</a>
|
871 | </li>
|
872 | <li class="menu-item -level-2"><a href="#scour.filter" class="link title link-scour.filter">scour.filter</a>
|
873 | </li>
|
874 | </ul>
|
875 | </li>
|
876 | <li class="menu-item -level-1"><a href="#thanks" class="link title link-thanks">Thanks</a>
|
877 | </li>
|
878 | <li class="menu-item -level-1 -parent"><span class="title">Appendix</span>
|
879 | <ul class="submenu">
|
880 | <li class="menu-item -level-2"><a href="HISTORY.html" class="link title link-history">Changelog</a>
|
881 | </li>
|
882 | <li class="menu-item -level-2"><a href="comparison.html" class="link title link-comparison">Comparison with others</a>
|
883 | </li>
|
884 | <li class="menu-item -level-2"><a href="extensions_example.html" class="link title link-extensions_example">Extensions example</a>
|
885 | </li>
|
886 | <li class="menu-item -level-2"><a href="redux_example.html" class="link title link-redux_example">Redux example</a>
|
887 | </li>
|
888 | </ul>
|
889 | </li>
|
890 | </ul>
|
891 | </li>
|
892 | </div>
|
893 | </div>
|
894 | </body>
|
895 | </html> |
\ | No newline at end of file |