Permalink
Browse files

0.4.0 is out, with OOP-style and chaining

  • Loading branch information...
jashkenas committed Nov 7, 2009
1 parent 4f0afda commit ed37b9df4953d554d3f72dd3b0d9df8fb1efad91
Showing with 135 additions and 13 deletions.
  1. +63 −3 index.html
  2. +35 −0 test/chaining.js
  3. +1 −0 test/test.html
  4. +12 −0 test/utility.js
  5. +1 −1 underscore-min.js
  6. +23 −9 underscore.js
View
@@ -107,16 +107,55 @@ <h2>Downloads <i style="padding-left: 12px; font-size:12px;">(Right-click, and u
<p>
<table>
<tr>
- <td><a href="underscore.js">Development Version (0.3.3)</a></td>
+ <td><a href="underscore.js">Development Version (0.4.0)</a></td>
<td><i>16kb, Uncompressed with Comments</i></td>
</tr>
<tr>
- <td><a href="underscore-min.js">Production Version (0.3.3)</a></td>
+ <td><a href="underscore-min.js">Production Version (0.4.0)</a></td>
<td><i>2kb, Packed and Gzipped</i></td>
</tr>
</table>
</p>
+ <h2>Object-Oriented and Functional Styles</h2>
+
+ <p>
+ You can use Underscore in either an object-oriented or a functional style,
+ depending on your preference. The following two lines of code are
+ identical ways to double a list of numbers.
+ </p>
+
+ <pre>
+_.map([1, 2, 3], function(n){ return n * 2; });
+_([1, 2, 3]).map(function(n){ return n * 2; });</pre>
+
+ <p>
+ Using the object-oriented style allows you to chain together methods. Calling
+ <tt>chain</tt> on a wrapped object will cause all future method calls to
+ return wrapped objects as well. When you've finished the computation,
+ use <tt>get</tt> to retrieve the final value. Here's an example of chaining
+ together a <b>map/flatten/reduce</b>, in order to get the word count of
+ every word in a song.
+ </p>
+
+<pre>
+var lyrics = [
+ {line : 1, words : "I'm a lumberjack and I'm okay"},
+ {line : 2, words : "I sleep all night and I work all day"},
+ {line : 3, words : "He's a lumberjack and he's okay"},
+ {line : 4, words : "He sleeps all night and he works all day"}
+];
+
+_(lyrics).chain()
+ .map(function(line) { return line.words.split(' '); })
+ .flatten()
+ .reduce({}, function(counts, word) {
+ counts[word] = (counts[word] || 0) + 1;
+ return counts;
+}).get();
+
+=&gt; returns a hash containing the word counts...</pre>
+
<h2>Table of Contents</h2>
<p>
@@ -742,6 +781,17 @@ <h2>Utility Functions</h2>
<pre>
_.uniqueId('contact_');
=&gt; 'contact_104'
+</pre>
+
+ <p id="functions">
+ <b class="header">functions</b><code>_.functions([prefix])</code>
+ <span class="alias">Alias: <b>methods</b></span>
+ <br />
+ Returns a sorted list of the name of every function in Underscore.
+ </p>
+ <pre>
+_.functions();
+=&gt; ["all", "any", "bind", "bindAll", "clone", "compact", "compose" ...
</pre>
<p id="template">
@@ -769,6 +819,16 @@ <h2>Utility Functions</h2>
<h2>Change Log</h2>
+ <p>
+ <b class="header">0.4.0</b><br />
+ All Underscore functions can now be called in an object-oriented style,
+ like so: <tt>_([1, 2, 3]).map(...);</tt>. Original patch provided by
+ <a href="http://macournoyer.com/">Marc-André Cournoyer</a>.
+ Wrapped objects can be chained through multiple
+ method invocations. A <a href="#functions"><tt>functions</tt></a> method
+ was added, providing a sorted list of all the functions in Underscore.
+ </p>
+
<p>
<b class="header">0.3.3</b><br />
Added the JavaScript 1.8 function <tt>reduceRight</tt>. Aliased it
@@ -787,7 +847,7 @@ <h2>Change Log</h2>
All iterators are now passed in the original collection as their third
argument, the same as JavaScript 1.6's <b>forEach</b>. Iterating over
objects is now called with <tt>(value, key, collection)</tt>, for details
- see <a href="#each">_.each</a>.
+ see <a href="#each"><tt>_.each</tt></a>.
</p>
<p>
View
@@ -0,0 +1,35 @@
+$(document).ready(function() {
+
+ module("Underscore chaining.");
+
+ test("chaining: map/flatten/reduce", function() {
+ var lyrics = [
+ "I'm a lumberjack and I'm okay",
+ "I sleep all night and I work all day",
+ "He's a lumberjack and he's okay",
+ "He sleeps all night and he works all day"
+ ];
+ var counts = _(lyrics).chain()
+ .map(function(line) { return line.split(''); })
+ .flatten()
+ .reduce({}, function(hash, l) {
+ hash[l] = hash[l] || 0;
+ hash[l]++;
+ return hash;
+ }).get();
+ ok(counts['a'] == 16 && counts['e'] == 10, 'counted all the letters in the song');
+ });
+
+ test("chaining: select/reject/sortBy", function() {
+ var numbers = [1,2,3,4,5,6,7,8,9,10];
+ numbers = _(numbers).chain().select(function(n) {
+ return n % 2 == 0;
+ }).reject(function(n) {
+ return n % 4 == 0;
+ }).sortBy(function(n) {
+ return -n;
+ }).get();
+ equals(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers");
+ });
+
+});
View
@@ -12,6 +12,7 @@
<script type="text/javascript" src="functions.js"></script>
<script type="text/javascript" src="objects.js"></script>
<script type="text/javascript" src="utility.js"></script>
+ <script type="text/javascript" src="chaining.js"></script>
<script type="text/javascript" src="speed.js"></script>
</head>
<body>
View
@@ -21,6 +21,18 @@ $(document).ready(function() {
equals(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids');
});
+ test("utility: functions", function() {
+ var expected = ["all", "any", "bind", "bindAll", "clone", "compact", "compose",
+ "defer", "delay", "detect", "each", "every", "extend", "filter", "first",
+ "flatten", "foldl", "foldr", "forEach", "functions", "identity", "include",
+ "indexOf", "inject", "intersect", "invoke", "isArray", "isElement", "isEqual",
+ "isFunction", "isUndefined", "keys", "last", "lastIndexOf", "map", "max",
+ "methods", "min", "pluck", "reduce", "reduceRight", "reject", "select",
+ "size", "some", "sortBy", "sortedIndex", "template", "toArray", "uniq",
+ "uniqueId", "values", "without", "wrap", "zip"];
+ ok(_(expected).isEqual(_.methods()), 'provides a sorted list of functions');
+ });
+
test("utility: template", function() {
var basicTemplate = _.template("<%= thing %> is gettin' on my noives!");
var result = basicTemplate({thing : 'This'});
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
Oops, something went wrong.

0 comments on commit ed37b9d

Please sign in to comment.