Skip to content

Commit 29e2c83

Browse files
committed
Underscore 1.0.4, with _.memoize
1 parent d629066 commit 29e2c83

File tree

6 files changed

+68
-29
lines changed

6 files changed

+68
-29
lines changed

index.html

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -108,18 +108,16 @@ <h1>Underscore.js</h1>
108108

109109
<h2>Downloads <i style="padding-left: 12px; font-size:12px;">(Right-click, and use "Save As")</i></h2>
110110

111-
<p>
112-
<table>
113-
<tr>
114-
<td><a href="underscore.js">Development Version (1.0.3)</a></td>
115-
<td><i>24kb, Uncompressed with Comments</i></td>
116-
</tr>
117-
<tr>
118-
<td><a href="underscore-min.js">Production Version (1.0.3)</a></td>
119-
<td><i>2.9kb, Packed and Gzipped</i></td>
120-
</tr>
121-
</table>
122-
</p>
111+
<table>
112+
<tr>
113+
<td><a href="underscore.js">Development Version (1.0.4)</a></td>
114+
<td><i>24kb, Uncompressed with Comments</i></td>
115+
</tr>
116+
<tr>
117+
<td><a href="underscore-min.js">Production Version (1.0.4)</a></td>
118+
<td><i>2.9kb, Packed and Gzipped</i></td>
119+
</tr>
120+
</table>
123121

124122
<h2>Table of Contents</h2>
125123

@@ -144,15 +142,16 @@ <h2>Table of Contents</h2>
144142
<br />
145143
<span class="methods"><a href="#first">first</a>, <a href="#rest">rest</a>, <a href="#last">last</a>,
146144
<a href="#compact">compact</a>, <a href="#flatten">flatten</a>, <a href="#without">without</a>, <a href="#uniq">uniq</a>,
147-
<a href="#intersect">intersect</a>, <a href="#zip">zip</a>, <a href="#indexOf">indexOf</a></span>,
145+
<a href="#intersect">intersect</a>, <a href="#zip">zip</a>, <a href="#indexOf">indexOf</a>,
148146
<a href="#lastIndexOf">lastIndexOf</a>, <a href="#range">range</a></span>
149147
</p>
150148

151149
<p>
152150
<b>Functions</b>
153151
<br />
154-
<span class="methods"><a href="#bind">bind</a>, <a href="#bindAll">bindAll</a>, <a href="#delay">delay</a>,
155-
<a href="#defer">defer</a>, <a href="#wrap">wrap</a></span>, <a href="#compose">compose</a></span>
152+
<span class="methods"><a href="#bind">bind</a>, <a href="#bindAll">bindAll</a>,
153+
<a href="#memoize">memoize</a>, <a href="#delay">delay</a>, <a href="#defer">defer</a>,
154+
<a href="#wrap">wrap</a>, <a href="#compose">compose</a></span>
156155
</p>
157156

158157
<p>
@@ -173,7 +172,7 @@ <h2>Table of Contents</h2>
173172
<br />
174173
<span class="methods"><a href="#noConflict">noConflict</a>,
175174
<a href="#identity">identity</a>, <a href="#times">times</a>,
176-
<a href="#breakLoop">breakLoop</a></span>, <a href="#mixin">mixin</a></span>,
175+
<a href="#breakLoop">breakLoop</a>, <a href="#mixin">mixin</a>,
177176
<a href="#uniqueId">uniqueId</a>, <a href="#template">template</a></span>
178177
</p>
179178

@@ -652,6 +651,21 @@ <h2>Function (uh, ahem) Functions</h2>
652651
_.bindAll(buttonView);
653652
jQuery('#underscore_button').bind('click', buttonView.onClick);
654653
=&gt; When the button is clicked, this.label will have the correct value...
654+
</pre>
655+
656+
<p id="memoize">
657+
<b class="header">memoize</b><code>_.memoize(function, [hashFunction])</code>
658+
<br />
659+
Memoizes a given <b>function</b> by caching the computed result. Useful
660+
for speeding up slow-running computations. If passed an optional
661+
<b>hashFunction</b>, it will be used to compute the hash key for storing
662+
the result, based on the arguments to the original function.
663+
</p>
664+
<pre>
665+
var fibonacci = function(n) {
666+
return n &lt; 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
667+
};
668+
var fastFibonacci = _.memoize(fibonacci);
655669
</pre>
656670

657671
<p id="delay">
@@ -1136,6 +1150,12 @@ <h2>Links &amp; Suggested Reading</h2>
11361150

11371151
<h2>Change Log</h2>
11381152

1153+
<p>
1154+
<b class="header">1.0.4</b><br />
1155+
Andri Möll contributed the <tt>_.memoize</tt> function, which can be
1156+
used to speed up expensive repeated computations by caching the results.
1157+
</p>
1158+
11391159
<p>
11401160
<b class="header">1.0.3</b><br />
11411161
Patch that makes <tt>_.isEqual</tt> return <tt>false</tt> if any property

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
"dependencies" : [],
99
"lib" : ".",
1010
"main" : "underscore.js",
11-
"version" : "1.0.3"
11+
"version" : "1.0.4"
1212
}

test/functions.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ $(document).ready(function() {
4545
equals(curly.sayHi(), 'hi: moe', 'calling bindAll with no arguments binds all functions to the object');
4646
});
4747

48+
test("functions: memoize", function() {
49+
var fib = function(n) {
50+
return n < 2 ? n : fib(n - 1) + fib(n - 2);
51+
};
52+
var fastFib = _.memoize(fib);
53+
equals(fib(10), 55, 'a memoized version of fibonacci produces identical results');
54+
equals(fastFib(10), 55, 'a memoized version of fibonacci produces identical results');
55+
});
56+
4857
asyncTest("functions: delay", function() {
4958
var delayed = false;
5059
_.delay(function(){ delayed = true; }, 100);

test/objects.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ $(document).ready(function() {
1616
"flatten", "foldl", "foldr", "forEach", "functions", "head", "identity", "include",
1717
"indexOf", "inject", "intersect", "invoke", "isArguments", "isArray", "isBoolean", "isDate", "isElement", "isEmpty", "isEqual",
1818
"isFunction", "isNaN", "isNull", "isNumber", "isRegExp", "isString", "isUndefined", "keys", "last", "lastIndexOf", "map", "max",
19-
"methods", "min", "mixin", "noConflict", "pluck", "range", "reduce", "reduceRight", "reject", "rest", "select",
19+
"memoize", "methods", "min", "mixin", "noConflict", "pluck", "range", "reduce", "reduceRight", "reject", "rest", "select",
2020
"size", "some", "sortBy", "sortedIndex", "tail", "tap", "template", "times", "toArray", "uniq",
2121
"uniqueId", "values", "without", "wrap", "zip"];
2222
same(expected, _.methods(_), 'provides a sorted list of functions');

underscore-min.js

Lines changed: 10 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

underscore.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
root._ = _;
5656

5757
// Current version.
58-
_.VERSION = '1.0.3';
58+
_.VERSION = '1.0.4';
5959

6060
// ------------------------ Collection Functions: ---------------------------
6161

@@ -375,6 +375,16 @@
375375
return obj;
376376
};
377377

378+
// Memoize an expensive function by storing its results.
379+
_.memoize = function(func, hasher) {
380+
var memo = {};
381+
hasher = hasher || _.identity;
382+
return function() {
383+
var key = hasher.apply(this, arguments);
384+
return key in memo ? memo[key] : (memo[key] = func.apply(this, arguments));
385+
};
386+
};
387+
378388
// Delays a function for the given number of milliseconds, and then calls
379389
// it with the arguments supplied.
380390
_.delay = function(func, wait) {

0 commit comments

Comments
 (0)