PageRenderTime 52ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/documentation/docs/underscore.html

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