/documentation/docs/underscore.html
HTML | 1892 lines | 1259 code | 633 blank | 0 comment | 0 complexity | b6c7530433edfb454865be08d4e16b4f MD5 | raw file
Large files files are truncated, but you can click here to view the full file
1<!DOCTYPE html> 2 3<html> 4<head> 5 <title>underscore.coffee</title> 6 <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 7 <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"> 8 <link rel="stylesheet" media="all" href="docco.css" /> 9</head> 10<body> 11 <div id="container"> 12 <div id="background"></div> 13 14 <ul class="sections"> 15 16 <li id="title"> 17 <div class="annotation"> 18 <h1>underscore.coffee</h1> 19 </div> 20 </li> 21 22 23 24 <li id="section-1"> 25 <div class="annotation"> 26 27 <div class="pilwrap "> 28 <a class="pilcrow" href="#section-1">¶</a> 29 </div> 30 <p><strong>Underscore.coffee 31(c) 2011 Jeremy Ashkenas, DocumentCloud Inc.</strong> 32Underscore is freely distributable under the terms of the 33<a href="http://en.wikipedia.org/wiki/MIT_License">MIT license</a>. 34Portions of Underscore are inspired by or borrowed from 35<a href="http://prototypejs.org/api">Prototype.js</a>, Oliver Steele's 36<a href="http://osteele.com">Functional</a>, and John Resig's 37<a href="http://ejohn.org">Micro-Templating</a>. 38For all details and documentation: 39<a href="http://documentcloud.github.com/underscore/">http://documentcloud.github.com/underscore/</a></p> 40<h2>Baseline setup</h2> 41 42 </div> 43 44 </li> 45 46 47 <li id="section-2"> 48 <div class="annotation"> 49 50 <div class="pilwrap "> 51 <a class="pilcrow" href="#section-2">¶</a> 52 </div> 53 <p>Establish the root object, <code>window</code> in the browser, or <code>global</code> on the server.</p> 54 55 </div> 56 57 <div class="content"><div class='highlight'><pre>root = <span class="keyword">this</span></pre></div></div> 58 59 </li> 60 61 62 <li id="section-3"> 63 <div class="annotation"> 64 65 <div class="pilwrap "> 66 <a class="pilcrow" href="#section-3">¶</a> 67 </div> 68 <p>Save the previous value of the <code>_</code> variable.</p> 69 70 </div> 71 72 <div class="content"><div class='highlight'><pre>previousUnderscore = root._</pre></div></div> 73 74 </li> 75 76 77 <li id="section-4"> 78 <div class="annotation"> 79 80 <div class="pilwrap "> 81 <a class="pilcrow" href="#section-4">¶</a> 82 </div> 83 <p>Establish the object that gets thrown to break out of a loop iteration. 84<code>StopIteration</code> is SOP on Mozilla.</p> 85 86 </div> 87 88 <div class="content"><div class='highlight'><pre>breaker = <span class="keyword">if</span> <span class="keyword">typeof</span>(StopIteration) <span class="keyword">is</span> <span class="string">'undefined'</span> <span class="keyword">then</span> <span class="string">'__break__'</span> <span class="keyword">else</span> StopIteration</pre></div></div> 89 90 </li> 91 92 93 <li id="section-5"> 94 <div class="annotation"> 95 96 <div class="pilwrap "> 97 <a class="pilcrow" href="#section-5">¶</a> 98 </div> 99 <p>Helper function to escape <strong>RegExp</strong> contents, because JS doesn't have one.</p> 100 101 </div> 102 103 <div class="content"><div class='highlight'><pre><span class="function"><span class="title">escapeRegExp</span></span> = (string) -> string.replace(<span class="regexp">/([.*+?^${}()|[\]\/\\])/g</span>, <span class="string">'\\$1'</span>)</pre></div></div> 104 105 </li> 106 107 108 <li id="section-6"> 109 <div class="annotation"> 110 111 <div class="pilwrap "> 112 <a class="pilcrow" href="#section-6">¶</a> 113 </div> 114 <p>Save bytes in the minified (but not gzipped) version:</p> 115 116 </div> 117 118 <div class="content"><div class='highlight'><pre>ArrayProto = Array.prototype 119ObjProto = Object.prototype</pre></div></div> 120 121 </li> 122 123 124 <li id="section-7"> 125 <div class="annotation"> 126 127 <div class="pilwrap "> 128 <a class="pilcrow" href="#section-7">¶</a> 129 </div> 130 <p>Create quick reference variables for speed access to core prototypes.</p> 131 132 </div> 133 134 <div class="content"><div class='highlight'><pre>slice = ArrayProto.slice 135unshift = ArrayProto.unshift 136toString = ObjProto.toString 137hasOwnProperty = ObjProto.hasOwnProperty 138propertyIsEnumerable = ObjProto.propertyIsEnumerable</pre></div></div> 139 140 </li> 141 142 143 <li id="section-8"> 144 <div class="annotation"> 145 146 <div class="pilwrap "> 147 <a class="pilcrow" href="#section-8">¶</a> 148 </div> 149 <p>All <strong>ECMA5</strong> native implementations we hope to use are declared here.</p> 150 151 </div> 152 153 <div class="content"><div class='highlight'><pre>nativeForEach = ArrayProto.forEach 154nativeMap = ArrayProto.map 155nativeReduce = ArrayProto.reduce 156nativeReduceRight = ArrayProto.reduceRight 157nativeFilter = ArrayProto.filter 158nativeEvery = ArrayProto.every 159nativeSome = ArrayProto.some 160nativeIndexOf = ArrayProto.indexOf 161nativeLastIndexOf = ArrayProto.lastIndexOf 162nativeIsArray = Array.isArray 163nativeKeys = Object.keys</pre></div></div> 164 165 </li> 166 167 168 <li id="section-9"> 169 <div class="annotation"> 170 171 <div class="pilwrap "> 172 <a class="pilcrow" href="#section-9">¶</a> 173 </div> 174 <p>Create a safe reference to the Underscore object for use below.</p> 175 176 </div> 177 178 <div class="content"><div class='highlight'><pre><span class="function"><span class="title">_</span></span> = (obj) -> <span class="keyword">new</span> wrapper(obj)</pre></div></div> 179 180 </li> 181 182 183 <li id="section-10"> 184 <div class="annotation"> 185 186 <div class="pilwrap "> 187 <a class="pilcrow" href="#section-10">¶</a> 188 </div> 189 <p>Export the Underscore object for <strong>CommonJS</strong>.</p> 190 191 </div> 192 193 <div class="content"><div class='highlight'><pre><span class="keyword">if</span> <span class="keyword">typeof</span>(exports) != <span class="string">'undefined'</span> <span class="keyword">then</span> exports._ = _</pre></div></div> 194 195 </li> 196 197 198 <li id="section-11"> 199 <div class="annotation"> 200 201 <div class="pilwrap "> 202 <a class="pilcrow" href="#section-11">¶</a> 203 </div> 204 <p>Export Underscore to global scope.</p> 205 206 </div> 207 208 <div class="content"><div class='highlight'><pre>root._ = _</pre></div></div> 209 210 </li> 211 212 213 <li id="section-12"> 214 <div class="annotation"> 215 216 <div class="pilwrap "> 217 <a class="pilcrow" href="#section-12">¶</a> 218 </div> 219 <p>Current version.</p> 220 221 </div> 222 223 <div class="content"><div class='highlight'><pre>_.VERSION = <span class="string">'1.1.0'</span></pre></div></div> 224 225 </li> 226 227 228 <li id="section-13"> 229 <div class="annotation"> 230 231 <div class="pilwrap for-h2"> 232 <a class="pilcrow" href="#section-13">¶</a> 233 </div> 234 <h2>Collection Functions</h2> 235 236 </div> 237 238 </li> 239 240 241 <li id="section-14"> 242 <div class="annotation"> 243 244 <div class="pilwrap "> 245 <a class="pilcrow" href="#section-14">¶</a> 246 </div> 247 <p>The cornerstone, an <strong>each</strong> implementation. 248Handles objects implementing <strong>forEach</strong>, arrays, and raw objects.</p> 249 250 </div> 251 252 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">each</span></span> = (obj, iterator, context) -> 253 <span class="keyword">try</span> 254 <span class="keyword">if</span> nativeForEach <span class="keyword">and</span> obj.forEach <span class="keyword">is</span> nativeForEach 255 obj.forEach iterator, context 256 <span class="keyword">else</span> <span class="keyword">if</span> _.isNumber obj.length 257 iterator.call context, obj[i], i, obj <span class="keyword">for</span> i <span class="keyword">in</span> [<span class="number">0.</span>..obj.length] 258 <span class="keyword">else</span> 259 iterator.call context, val, key, obj <span class="keyword">for</span> own key, val <span class="keyword">of</span> obj 260 <span class="keyword">catch</span> e 261 <span class="keyword">throw</span> e <span class="keyword">if</span> e <span class="keyword">isnt</span> breaker 262 obj</pre></div></div> 263 264 </li> 265 266 267 <li id="section-15"> 268 <div class="annotation"> 269 270 <div class="pilwrap "> 271 <a class="pilcrow" href="#section-15">¶</a> 272 </div> 273 <p>Return the results of applying the iterator to each element. Use JavaScript 2741.6's version of <strong>map</strong>, if possible.</p> 275 276 </div> 277 278 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">map</span></span> = (obj, iterator, context) -> 279 <span class="keyword">return</span> obj.map(iterator, context) <span class="keyword">if</span> nativeMap <span class="keyword">and</span> obj.map <span class="keyword">is</span> nativeMap 280 results = [] 281 _.each obj, (value, index, list) -> 282 results.push iterator.call context, value, index, list 283 results</pre></div></div> 284 285 </li> 286 287 288 <li id="section-16"> 289 <div class="annotation"> 290 291 <div class="pilwrap "> 292 <a class="pilcrow" href="#section-16">¶</a> 293 </div> 294 <p><strong>Reduce</strong> builds up a single result from a list of values. Also known as 295<strong>inject</strong>, or <strong>foldl</strong>. Uses JavaScript 1.8's version of <strong>reduce</strong>, if possible.</p> 296 297 </div> 298 299 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">reduce</span></span> = (obj, iterator, memo, context) -> 300 <span class="keyword">if</span> nativeReduce <span class="keyword">and</span> obj.reduce <span class="keyword">is</span> nativeReduce 301 iterator = _.bind iterator, context <span class="keyword">if</span> context 302 <span class="keyword">return</span> obj.reduce iterator, memo 303 _.each obj, (value, index, list) -> 304 memo = iterator.call context, memo, value, index, list 305 memo</pre></div></div> 306 307 </li> 308 309 310 <li id="section-17"> 311 <div class="annotation"> 312 313 <div class="pilwrap "> 314 <a class="pilcrow" href="#section-17">¶</a> 315 </div> 316 <p>The right-associative version of <strong>reduce</strong>, also known as <strong>foldr</strong>. Uses 317JavaScript 1.8's version of <strong>reduceRight</strong>, if available.</p> 318 319 </div> 320 321 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">reduceRight</span></span> = (obj, iterator, memo, context) -> 322 <span class="keyword">if</span> nativeReduceRight <span class="keyword">and</span> obj.reduceRight <span class="keyword">is</span> nativeReduceRight 323 iterator = _.bind iterator, context <span class="keyword">if</span> context 324 <span class="keyword">return</span> obj.reduceRight iterator, memo 325 reversed = _.clone(_.toArray(obj)).reverse() 326 _.reduce reversed, iterator, memo, context</pre></div></div> 327 328 </li> 329 330 331 <li id="section-18"> 332 <div class="annotation"> 333 334 <div class="pilwrap "> 335 <a class="pilcrow" href="#section-18">¶</a> 336 </div> 337 <p>Return the first value which passes a truth test.</p> 338 339 </div> 340 341 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">detect</span></span> = (obj, iterator, context) -> 342 result = <span class="literal">null</span> 343 _.each obj, (value, index, list) -> 344 <span class="keyword">if</span> iterator.call context, value, index, list 345 result = value 346 _.breakLoop() 347 result</pre></div></div> 348 349 </li> 350 351 352 <li id="section-19"> 353 <div class="annotation"> 354 355 <div class="pilwrap "> 356 <a class="pilcrow" href="#section-19">¶</a> 357 </div> 358 <p>Return all the elements that pass a truth test. Use JavaScript 1.6's 359<strong>filter</strong>, if it exists.</p> 360 361 </div> 362 363 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">filter</span></span> = (obj, iterator, context) -> 364 <span class="keyword">return</span> obj.filter iterator, context <span class="keyword">if</span> nativeFilter <span class="keyword">and</span> obj.filter <span class="keyword">is</span> nativeFilter 365 results = [] 366 _.each obj, (value, index, list) -> 367 results.push value <span class="keyword">if</span> iterator.call context, value, index, list 368 results</pre></div></div> 369 370 </li> 371 372 373 <li id="section-20"> 374 <div class="annotation"> 375 376 <div class="pilwrap "> 377 <a class="pilcrow" href="#section-20">¶</a> 378 </div> 379 <p>Return all the elements for which a truth test fails.</p> 380 381 </div> 382 383 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">reject</span></span> = (obj, iterator, context) -> 384 results = [] 385 _.each obj, (value, index, list) -> 386 results.push value <span class="keyword">if</span> <span class="keyword">not</span> iterator.call context, value, index, list 387 results</pre></div></div> 388 389 </li> 390 391 392 <li id="section-21"> 393 <div class="annotation"> 394 395 <div class="pilwrap "> 396 <a class="pilcrow" href="#section-21">¶</a> 397 </div> 398 <p>Determine whether all of the elements match a truth test. Delegate to 399JavaScript 1.6's <strong>every</strong>, if it is present.</p> 400 401 </div> 402 403 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">every</span></span> = (obj, iterator, context) -> 404 iterator ||= _.identity 405 <span class="keyword">return</span> obj.every iterator, context <span class="keyword">if</span> nativeEvery <span class="keyword">and</span> obj.every <span class="keyword">is</span> nativeEvery 406 result = <span class="literal">true</span> 407 _.each obj, (value, index, list) -> 408 _.breakLoop() <span class="keyword">unless</span> (result = result <span class="keyword">and</span> iterator.call(context, value, index, list)) 409 result</pre></div></div> 410 411 </li> 412 413 414 <li id="section-22"> 415 <div class="annotation"> 416 417 <div class="pilwrap "> 418 <a class="pilcrow" href="#section-22">¶</a> 419 </div> 420 <p>Determine if at least one element in the object matches a truth test. Use 421JavaScript 1.6's <strong>some</strong>, if it exists.</p> 422 423 </div> 424 425 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">some</span></span> = (obj, iterator, context) -> 426 iterator ||= _.identity 427 <span class="keyword">return</span> obj.some iterator, context <span class="keyword">if</span> nativeSome <span class="keyword">and</span> obj.some <span class="keyword">is</span> nativeSome 428 result = <span class="literal">false</span> 429 _.each obj, (value, index, list) -> 430 _.breakLoop() <span class="keyword">if</span> (result = iterator.call(context, value, index, list)) 431 result</pre></div></div> 432 433 </li> 434 435 436 <li id="section-23"> 437 <div class="annotation"> 438 439 <div class="pilwrap "> 440 <a class="pilcrow" href="#section-23">¶</a> 441 </div> 442 <p>Determine if a given value is included in the array or object, 443based on <code>===</code>.</p> 444 445 </div> 446 447 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">include</span></span> = (obj, target) -> 448 <span class="keyword">return</span> _.indexOf(obj, target) <span class="keyword">isnt</span> -<span class="number">1</span> <span class="keyword">if</span> nativeIndexOf <span class="keyword">and</span> obj.indexOf <span class="keyword">is</span> nativeIndexOf 449 <span class="keyword">return</span> <span class="literal">true</span> <span class="keyword">for</span> own key, val <span class="keyword">of</span> obj <span class="keyword">when</span> val <span class="keyword">is</span> target 450 <span class="literal">false</span></pre></div></div> 451 452 </li> 453 454 455 <li id="section-24"> 456 <div class="annotation"> 457 458 <div class="pilwrap "> 459 <a class="pilcrow" href="#section-24">¶</a> 460 </div> 461 <p>Invoke a method with arguments on every item in a collection.</p> 462 463 </div> 464 465 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">invoke</span></span> = (obj, method) -> 466 args = _.rest arguments, <span class="number">2</span> 467 (<span class="keyword">if</span> method <span class="keyword">then</span> val[method] <span class="keyword">else</span> val).apply(val, args) <span class="keyword">for</span> val <span class="keyword">in</span> obj</pre></div></div> 468 469 </li> 470 471 472 <li id="section-25"> 473 <div class="annotation"> 474 475 <div class="pilwrap "> 476 <a class="pilcrow" href="#section-25">¶</a> 477 </div> 478 <p>Convenience version of a common use case of <strong>map</strong>: fetching a property.</p> 479 480 </div> 481 482 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">pluck</span></span> = (obj, key) -> 483 _.map(obj, (val) -> val[key])</pre></div></div> 484 485 </li> 486 487 488 <li id="section-26"> 489 <div class="annotation"> 490 491 <div class="pilwrap "> 492 <a class="pilcrow" href="#section-26">¶</a> 493 </div> 494 <p>Return the maximum item or (item-based computation).</p> 495 496 </div> 497 498 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">max</span></span> = (obj, iterator, context) -> 499 <span class="keyword">return</span> Math.max.apply(Math, obj) <span class="keyword">if</span> <span class="keyword">not</span> iterator <span class="keyword">and</span> _.isArray(obj) 500 result = computed: -Infinity 501 _.each obj, (value, index, list) -> 502 computed = <span class="keyword">if</span> iterator <span class="keyword">then</span> iterator.call(context, value, index, list) <span class="keyword">else</span> value 503 computed >= result.computed <span class="keyword">and</span> (result = {value: value, computed: computed}) 504 result.value</pre></div></div> 505 506 </li> 507 508 509 <li id="section-27"> 510 <div class="annotation"> 511 512 <div class="pilwrap "> 513 <a class="pilcrow" href="#section-27">¶</a> 514 </div> 515 <p>Return the minimum element (or element-based computation).</p> 516 517 </div> 518 519 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">min</span></span> = (obj, iterator, context) -> 520 <span class="keyword">return</span> Math.min.apply(Math, obj) <span class="keyword">if</span> <span class="keyword">not</span> iterator <span class="keyword">and</span> _.isArray(obj) 521 result = computed: Infinity 522 _.each obj, (value, index, list) -> 523 computed = <span class="keyword">if</span> iterator <span class="keyword">then</span> iterator.call(context, value, index, list) <span class="keyword">else</span> value 524 computed < result.computed <span class="keyword">and</span> (result = {value: value, computed: computed}) 525 result.value</pre></div></div> 526 527 </li> 528 529 530 <li id="section-28"> 531 <div class="annotation"> 532 533 <div class="pilwrap "> 534 <a class="pilcrow" href="#section-28">¶</a> 535 </div> 536 <p>Sort the object's values by a criterion produced by an iterator.</p> 537 538 </div> 539 540 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">sortBy</span></span> = (obj, iterator, context) -> 541 _.pluck(((_.map obj, (value, index, list) -> 542 {value: value, criteria: iterator.call(context, value, index, list)} 543 ).sort((left, right) -> 544 a = left.criteria; b = right.criteria 545 <span class="keyword">if</span> a < b <span class="keyword">then</span> -<span class="number">1</span> <span class="keyword">else</span> <span class="keyword">if</span> a > b <span class="keyword">then</span> <span class="number">1</span> <span class="keyword">else</span> <span class="number">0</span> 546 )), <span class="string">'value'</span>)</pre></div></div> 547 548 </li> 549 550 551 <li id="section-29"> 552 <div class="annotation"> 553 554 <div class="pilwrap "> 555 <a class="pilcrow" href="#section-29">¶</a> 556 </div> 557 <p>Use a comparator function to figure out at what index an object should 558be inserted so as to maintain order. Uses binary search.</p> 559 560 </div> 561 562 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">sortedIndex</span></span> = (array, obj, iterator) -> 563 iterator ||= _.identity 564 low = <span class="number">0</span> 565 high = array.length 566 <span class="keyword">while</span> low < high 567 mid = (low + high) >> <span class="number">1</span> 568 <span class="keyword">if</span> iterator(array[mid]) < iterator(obj) <span class="keyword">then</span> low = mid + <span class="number">1</span> <span class="keyword">else</span> high = mid 569 low</pre></div></div> 570 571 </li> 572 573 574 <li id="section-30"> 575 <div class="annotation"> 576 577 <div class="pilwrap "> 578 <a class="pilcrow" href="#section-30">¶</a> 579 </div> 580 <p>Convert anything iterable into a real, live array.</p> 581 582 </div> 583 584 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">toArray</span></span> = (iterable) -> 585 <span class="keyword">return</span> [] <span class="keyword">if</span> (!iterable) 586 <span class="keyword">return</span> iterable.toArray() <span class="keyword">if</span> (iterable.toArray) 587 <span class="keyword">return</span> iterable <span class="keyword">if</span> (_.isArray(iterable)) 588 <span class="keyword">return</span> slice.call(iterable) <span class="keyword">if</span> (_.isArguments(iterable)) 589 _.values(iterable)</pre></div></div> 590 591 </li> 592 593 594 <li id="section-31"> 595 <div class="annotation"> 596 597 <div class="pilwrap "> 598 <a class="pilcrow" href="#section-31">¶</a> 599 </div> 600 <p>Return the number of elements in an object.</p> 601 602 </div> 603 604 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">size</span></span> = (obj) -> _.toArray(obj).length</pre></div></div> 605 606 </li> 607 608 609 <li id="section-32"> 610 <div class="annotation"> 611 612 <div class="pilwrap for-h2"> 613 <a class="pilcrow" href="#section-32">¶</a> 614 </div> 615 <h2>Array Functions</h2> 616 617 </div> 618 619 </li> 620 621 622 <li id="section-33"> 623 <div class="annotation"> 624 625 <div class="pilwrap "> 626 <a class="pilcrow" href="#section-33">¶</a> 627 </div> 628 <p>Get the first element of an array. Passing <code>n</code> will return the first N 629values in the array. Aliased as <strong>head</strong>. The <code>guard</code> check allows it to work 630with <strong>map</strong>.</p> 631 632 </div> 633 634 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">first</span></span> = (array, n, guard) -> 635 <span class="keyword">if</span> n <span class="keyword">and</span> <span class="keyword">not</span> guard <span class="keyword">then</span> slice.call(array, <span class="number">0</span>, n) <span class="keyword">else</span> array[<span class="number">0</span>]</pre></div></div> 636 637 </li> 638 639 640 <li id="section-34"> 641 <div class="annotation"> 642 643 <div class="pilwrap "> 644 <a class="pilcrow" href="#section-34">¶</a> 645 </div> 646 <p>Returns everything but the first entry of the array. Aliased as <strong>tail</strong>. 647Especially useful on the arguments object. Passing an <code>index</code> will return 648the rest of the values in the array from that index onward. The <code>guard</code> 649check allows it to work with <strong>map</strong>.</p> 650 651 </div> 652 653 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">rest</span></span> = (array, index, guard) -> 654 slice.call(array, <span class="keyword">if</span> _.isUndefined(index) <span class="keyword">or</span> guard <span class="keyword">then</span> <span class="number">1</span> <span class="keyword">else</span> index)</pre></div></div> 655 656 </li> 657 658 659 <li id="section-35"> 660 <div class="annotation"> 661 662 <div class="pilwrap "> 663 <a class="pilcrow" href="#section-35">¶</a> 664 </div> 665 <p>Get the last element of an array.</p> 666 667 </div> 668 669 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">last</span></span> = (array) -> array[array.length - <span class="number">1</span>]</pre></div></div> 670 671 </li> 672 673 674 <li id="section-36"> 675 <div class="annotation"> 676 677 <div class="pilwrap "> 678 <a class="pilcrow" href="#section-36">¶</a> 679 </div> 680 <p>Trim out all falsy values from an array.</p> 681 682 </div> 683 684 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">compact</span></span> = (array) -> item <span class="keyword">for</span> item <span class="keyword">in</span> array <span class="keyword">when</span> item</pre></div></div> 685 686 </li> 687 688 689 <li id="section-37"> 690 <div class="annotation"> 691 692 <div class="pilwrap "> 693 <a class="pilcrow" href="#section-37">¶</a> 694 </div> 695 <p>Return a completely flattened version of an array.</p> 696 697 </div> 698 699 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">flatten</span></span> = (array) -> 700 _.reduce array, (memo, value) -> 701 <span class="keyword">return</span> memo.concat(_.flatten(value)) <span class="keyword">if</span> _.isArray value 702 memo.push value 703 memo 704 , []</pre></div></div> 705 706 </li> 707 708 709 <li id="section-38"> 710 <div class="annotation"> 711 712 <div class="pilwrap "> 713 <a class="pilcrow" href="#section-38">¶</a> 714 </div> 715 <p>Return a version of the array that does not contain the specified value(s).</p> 716 717 </div> 718 719 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">without</span></span> = (array) -> 720 values = _.rest arguments 721 val <span class="keyword">for</span> val <span class="keyword">in</span> _.toArray(array) <span class="keyword">when</span> <span class="keyword">not</span> _.include values, val</pre></div></div> 722 723 </li> 724 725 726 <li id="section-39"> 727 <div class="annotation"> 728 729 <div class="pilwrap "> 730 <a class="pilcrow" href="#section-39">¶</a> 731 </div> 732 <p>Produce a duplicate-free version of the array. If the array has already 733been sorted, you have the option of using a faster algorithm.</p> 734 735 </div> 736 737 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">uniq</span></span> = (array, isSorted) -> 738 memo = [] 739 <span class="keyword">for</span> el, i <span class="keyword">in</span> _.toArray array 740 memo.push el <span class="keyword">if</span> i <span class="keyword">is</span> <span class="number">0</span> || (<span class="keyword">if</span> isSorted <span class="keyword">is</span> <span class="literal">true</span> <span class="keyword">then</span> _.last(memo) <span class="keyword">isnt</span> el <span class="keyword">else</span> <span class="keyword">not</span> _.include(memo, el)) 741 memo</pre></div></div> 742 743 </li> 744 745 746 <li id="section-40"> 747 <div class="annotation"> 748 749 <div class="pilwrap "> 750 <a class="pilcrow" href="#section-40">¶</a> 751 </div> 752 <p>Produce an array that contains every item shared between all the 753passed-in arrays.</p> 754 755 </div> 756 757 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">intersect</span></span> = (array) -> 758 rest = _.rest arguments 759 _.select _.uniq(array), (item) -> 760 _.all rest, (other) -> 761 _.indexOf(other, item) >= <span class="number">0</span></pre></div></div> 762 763 </li> 764 765 766 <li id="section-41"> 767 <div class="annotation"> 768 769 <div class="pilwrap "> 770 <a class="pilcrow" href="#section-41">¶</a> 771 </div> 772 <p>Zip together multiple lists into a single array -- elements that share 773an index go together.</p> 774 775 </div> 776 777 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">zip</span></span> = -> 778 length = _.max _.pluck arguments, <span class="string">'length'</span> 779 results = <span class="keyword">new</span> Array length 780 <span class="keyword">for</span> i <span class="keyword">in</span> [<span class="number">0.</span>..length] 781 results[i] = _.pluck arguments, String i 782 results</pre></div></div> 783 784 </li> 785 786 787 <li id="section-42"> 788 <div class="annotation"> 789 790 <div class="pilwrap "> 791 <a class="pilcrow" href="#section-42">¶</a> 792 </div> 793 <p>If the browser doesn't supply us with <strong>indexOf</strong> (I'm looking at you, MSIE), 794we need this function. Return the position of the first occurrence of an 795item in an array, or -1 if the item is not included in the array.</p> 796 797 </div> 798 799 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">indexOf</span></span> = (array, item) -> 800 <span class="keyword">return</span> array.indexOf item <span class="keyword">if</span> nativeIndexOf <span class="keyword">and</span> array.indexOf <span class="keyword">is</span> nativeIndexOf 801 i = <span class="number">0</span>; l = array.length 802 <span class="keyword">while</span> l - i 803 <span class="keyword">if</span> array[i] <span class="keyword">is</span> item <span class="keyword">then</span> <span class="keyword">return</span> i <span class="keyword">else</span> i++ 804 -<span class="number">1</span></pre></div></div> 805 806 </li> 807 808 809 <li id="section-43"> 810 <div class="annotation"> 811 812 <div class="pilwrap "> 813 <a class="pilcrow" href="#section-43">¶</a> 814 </div> 815 <p>Provide JavaScript 1.6's <strong>lastIndexOf</strong>, delegating to the native function, 816if possible.</p> 817 818 </div> 819 820 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">lastIndexOf</span></span> = (array, item) -> 821 <span class="keyword">return</span> array.lastIndexOf(item) <span class="keyword">if</span> nativeLastIndexOf <span class="keyword">and</span> array.lastIndexOf <span class="keyword">is</span> nativeLastIndexOf 822 i = array.length 823 <span class="keyword">while</span> i 824 <span class="keyword">if</span> array[i] <span class="keyword">is</span> item <span class="keyword">then</span> <span class="keyword">return</span> i <span class="keyword">else</span> i-- 825 -<span class="number">1</span></pre></div></div> 826 827 </li> 828 829 830 <li id="section-44"> 831 <div class="annotation"> 832 833 <div class="pilwrap "> 834 <a class="pilcrow" href="#section-44">¶</a> 835 </div> 836 <p>Generate an integer Array containing an arithmetic progression. A port of 837<a href="http://docs.python.org/library/functions.html#range">the native Python <strong>range</strong> function</a>.</p> 838 839 </div> 840 841 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">range</span></span> = (start, stop, step) -> 842 a = arguments 843 solo = a.length <= <span class="number">1</span> 844 i = start = <span class="keyword">if</span> solo <span class="keyword">then</span> <span class="number">0</span> <span class="keyword">else</span> a[<span class="number">0</span>] 845 stop = <span class="keyword">if</span> solo <span class="keyword">then</span> a[<span class="number">0</span>] <span class="keyword">else</span> a[<span class="number">1</span>] 846 step = a[<span class="number">2</span>] <span class="keyword">or</span> <span class="number">1</span> 847 len = Math.ceil((stop - start) / step) 848 <span class="keyword">return</span> [] <span class="keyword">if</span> len <= <span class="number">0</span> 849 range = <span class="keyword">new</span> Array len 850 idx = <span class="number">0</span> 851 <span class="keyword">loop</span> 852 <span class="keyword">return</span> range <span class="keyword">if</span> (<span class="keyword">if</span> step > <span class="number">0</span> <span class="keyword">then</span> i - stop <span class="keyword">else</span> stop - i) >= <span class="number">0</span> 853 range[idx] = i 854 idx++ 855 i+= step</pre></div></div> 856 857 </li> 858 859 860 <li id="section-45"> 861 <div class="annotation"> 862 863 <div class="pilwrap for-h2"> 864 <a class="pilcrow" href="#section-45">¶</a> 865 </div> 866 <h2>Function Functions</h2> 867 868 </div> 869 870 </li> 871 872 873 <li id="section-46"> 874 <div class="annotation"> 875 876 <div class="pilwrap "> 877 <a class="pilcrow" href="#section-46">¶</a> 878 </div> 879 <p>Create a function bound to a given object (assigning <code>this</code>, and arguments, 880optionally). Binding with arguments is also known as <strong>curry</strong>.</p> 881 882 </div> 883 884 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">bind</span></span> = (func, obj) -> 885 args = _.rest arguments, <span class="number">2</span> 886 -> func.apply obj <span class="keyword">or</span> root, args.concat arguments</pre></div></div> 887 888 </li> 889 890 891 <li id="section-47"> 892 <div class="annotation"> 893 894 <div class="pilwrap "> 895 <a class="pilcrow" href="#section-47">¶</a> 896 </div> 897 <p>Bind all of an object's methods to that object. Useful for ensuring that 898all callbacks defined on an object belong to it.</p> 899 900 </div> 901 902 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">bindAll</span></span> = (obj) -> 903 funcs = <span class="keyword">if</span> arguments.length > <span class="number">1</span> <span class="keyword">then</span> _.rest(arguments) <span class="keyword">else</span> _.functions(obj) 904 _.each funcs, (f) -> obj[f] = _.bind obj[f], obj 905 obj</pre></div></div> 906 907 </li> 908 909 910 <li id="section-48"> 911 <div class="annotation"> 912 913 <div class="pilwrap "> 914 <a class="pilcrow" href="#section-48">¶</a> 915 </div> 916 <p>Delays a function for the given number of milliseconds, and then calls 917it with the arguments supplied.</p> 918 919 </div> 920 921 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">delay</span></span> = (func, wait) -> 922 args = _.rest arguments, <span class="number">2</span> 923 setTimeout((-> func.apply(func, args)), wait)</pre></div></div> 924 925 </li> 926 927 928 <li id="section-49"> 929 <div class="annotation"> 930 931 <div class="pilwrap "> 932 <a class="pilcrow" href="#section-49">¶</a> 933 </div> 934 <p>Memoize an expensive function by storing its results.</p> 935 936 </div> 937 938 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">memoize</span></span> = (func, hasher) -> 939 memo = {} 940 hasher <span class="keyword">or</span>= _.identity 941 -> 942 key = hasher.apply <span class="keyword">this</span>, arguments 943 <span class="keyword">return</span> memo[key] <span class="keyword">if</span> key <span class="keyword">of</span> memo 944 memo[key] = func.apply <span class="keyword">this</span>, arguments</pre></div></div> 945 946 </li> 947 948 949 <li id="section-50"> 950 <div class="annotation"> 951 952 <div class="pilwrap "> 953 <a class="pilcrow" href="#section-50">¶</a> 954 </div> 955 <p>Defers a function, scheduling it to run after the current call stack has 956cleared.</p> 957 958 </div> 959 960 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">defer</span></span> = (func) -> 961 _.delay.apply _, [func, <span class="number">1</span>].concat _.rest arguments</pre></div></div> 962 963 </li> 964 965 966 <li id="section-51"> 967 <div class="annotation"> 968 969 <div class="pilwrap "> 970 <a class="pilcrow" href="#section-51">¶</a> 971 </div> 972 <p>Returns the first function passed as an argument to the second, 973allowing you to adjust arguments, run code before and after, and 974conditionally execute the original function.</p> 975 976 </div> 977 978 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">wrap</span></span> = (func, wrapper) -> 979 -> wrapper.apply wrapper, [func].concat arguments</pre></div></div> 980 981 </li> 982 983 984 <li id="section-52"> 985 <div class="annotation"> 986 987 <div class="pilwrap "> 988 <a class="pilcrow" href="#section-52">¶</a> 989 </div> 990 <p>Returns a function that is the composition of a list of functions, each 991consuming the return value of the function that follows.</p> 992 993 </div> 994 995 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">compose</span></span> = -> 996 funcs = arguments 997 -> 998 args = arguments 999 <span class="keyword">for</span> i <span class="keyword">in</span> [funcs.length - <span class="number">1.</span><span class="number">.0</span>] <span class="keyword">by</span> -<span class="number">1</span> 1000 args = [funcs[i].apply(<span class="keyword">this</span>, args)] 1001 args[<span class="number">0</span>]</pre></div></div> 1002 1003 </li> 1004 1005 1006 <li id="section-53"> 1007 <div class="annotation"> 1008 1009 <div class="pilwrap for-h2"> 1010 <a class="pilcrow" href="#section-53">¶</a> 1011 </div> 1012 <h2>Object Functions</h2> 1013 1014 </div> 1015 1016 </li> 1017 1018 1019 <li id="section-54"> 1020 <div class="annotation"> 1021 1022 <div class="pilwrap "> 1023 <a class="pilcrow" href="#section-54">¶</a> 1024 </div> 1025 <p>Retrieve the names of an object's properties.</p> 1026 1027 </div> 1028 1029 <div class="content"><div class='highlight'><pre>_.keys = nativeKeys <span class="keyword">or</span> (obj) -> 1030 <span class="keyword">return</span> _.range <span class="number">0</span>, obj.length <span class="keyword">if</span> _.isArray(obj) 1031 key <span class="keyword">for</span> key, val <span class="keyword">of</span> obj</pre></div></div> 1032 1033 </li> 1034 1035 1036 <li id="section-55"> 1037 <div class="annotation"> 1038 1039 <div class="pilwrap "> 1040 <a class="pilcrow" href="#section-55">¶</a> 1041 </div> 1042 <p>Retrieve the values of an object's properties.</p> 1043 1044 </div> 1045 1046 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">values</span></span> = (obj) -> 1047 _.map obj, _.identity</pre></div></div> 1048 1049 </li> 1050 1051 1052 <li id="section-56"> 1053 <div class="annotation"> 1054 1055 <div class="pilwrap "> 1056 <a class="pilcrow" href="#section-56">¶</a> 1057 </div> 1058 <p>Return a sorted list of the function names available in Underscore.</p> 1059 1060 </div> 1061 1062 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">functions</span></span> = (obj) -> 1063 _.filter(_.keys(obj), (key) -> _.isFunction(obj[key])).sort()</pre></div></div> 1064 1065 </li> 1066 1067 1068 <li id="section-57"> 1069 <div class="annotation"> 1070 1071 <div class="pilwrap "> 1072 <a class="pilcrow" href="#section-57">¶</a> 1073 </div> 1074 <p>Extend a given object with all of the properties in a source object.</p> 1075 1076 </div> 1077 1078 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">extend</span></span> = (obj) -> 1079 <span class="keyword">for</span> source <span class="keyword">in</span> _.rest(arguments) 1080 obj[key] = val <span class="keyword">for</span> key, val <span class="keyword">of</span> source 1081 obj</pre></div></div> 1082 1083 </li> 1084 1085 1086 <li id="section-58"> 1087 <div class="annotation"> 1088 1089 <div class="pilwrap "> 1090 <a class="pilcrow" href="#section-58">¶</a> 1091 </div> 1092 <p>Create a (shallow-cloned) duplicate of an object.</p> 1093 1094 </div> 1095 1096 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">clone</span></span> = (obj) -> 1097 <span class="keyword">return</span> obj.slice <span class="number">0</span> <span class="keyword">if</span> _.isArray obj 1098 _.extend {}, obj</pre></div></div> 1099 1100 </li> 1101 1102 1103 <li id="section-59"> 1104 <div class="annotation"> 1105 1106 <div class="pilwrap "> 1107 <a class="pilcrow" href="#section-59">¶</a> 1108 </div> 1109 <p>Invokes interceptor with the obj, and then returns obj. 1110The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain.</p> 1111 1112 </div> 1113 1114 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">tap</span></span> = (obj, interceptor) -> 1115 interceptor obj 1116 obj</pre></div></div> 1117 1118 </li> 1119 1120 1121 <li id="section-60"> 1122 <div class="annotation"> 1123 1124 <div class="pilwrap "> 1125 <a class="pilcrow" href="#section-60">¶</a> 1126 </div> 1127 <p>Perform a deep comparison to check if two objects are equal.</p> 1128 1129 </div> 1130 1131 <div class="content"><div class='highlight'><pre>_.<span class="function"><span class="title">isEqual</span></span> = (a, b) -></pre></div></div> 1132 1133 </li> 1134 1135 1136 <li id="section-61"> 1137 <div class="annotation"> 1138 1139 <div class="pilwrap "> 1140 <a class="pilcrow" href="#section-61">¶</a> 1141 </div> 1142 <p>Check object identity.</p> 1143 1144 </div> 1145 1146 <div class="content"><div class='highlight'><pre> <span class="keyword">return</span> <span class="literal">true</span> <span class="keyword">if</span> a <span class="keyword">is</span> b</pre></div></div> 1147 1148 </li> 1149 1150 1151 <li id="section-62"> 1152 <div class="annotation"> 1153 1154 <div class="pilwrap "> 1155 <a class="pilcrow" href="#section-62">¶</a> 1156 </div> 1157 <p>Different types?</p> 1158 1159 </div> 1160 1161 <div class="content"><div class='highlight'><pre> atype = <span class="keyword">typeof</span>(a); btype = <span class="keyword">typeof</span>(b) 1162 <span class="keyword">return</span> <span class="literal">false</span> <span class="keyword">if</span> atype <span class="keyword">isnt</span> btype</pre></div></div> 1163 1164 </li> 1165 1166 1167 <li id="section-63"> 1168 <div class="annotation"> 1169 1170 <div class="pilwrap "> 1171 <a class="pilcrow" href="#section-63">¶</a> 1172 </div> 1173 <p>Basic equality test (watch out for coercions).</p> 1174 1175 </div> 1176 1177 <div class="content"><div class='highlight'><pre> <span class="keyword">return</span> <span class="literal">true</span> <span class="keyword">if</span> `<span class="javascript">a == b</span>`</pre></div></div> 1178 1179 </li> 1180 1181 1182 <li id="section-64"> 1183 <div class="annotation"> 1184 1185 <div class="pilwrap "> 1186 <a class="pilcrow" href="#section-64">¶</a> 1187 </div> 1188 <p>One is falsy and the other truthy.</p> 1189 1190 …
Large files files are truncated, but you can click here to view the full file