Permalink
Browse files

Underscore 0.4.5, with first/rest, head/tail, and all Array functions…

… guaranteed to work on 'arguments' objects. Many method implementations reworked to use _.rest()
  • Loading branch information...
1 parent b5f111e commit ae968a6ea06dd4fd6f5184b3e6d14f9a077b3d01 @jashkenas jashkenas committed Nov 19, 2009
Showing with 113 additions and 90 deletions.
  1. +35 −8 index.html
  2. +41 −28 test/arrays.js
  3. +3 −3 test/utility.js
  4. +11 −11 underscore-min.js
  5. +23 −40 underscore.js
View
@@ -107,11 +107,11 @@
<p>
<table>
<tr>
- <td><a href="underscore.js">Development Version (0.4.4)</a></td>
+ <td><a href="underscore.js">Development Version (0.4.5)</a></td>
<td><i>18kb, Uncompressed with Comments</i></td>
</tr>
<tr>
- <td><a href="underscore-min.js">Production Version (0.4.4)</a></td>
+ <td><a href="underscore-min.js">Production Version (0.4.5)</a></td>
<td><i>2kb, Packed and Gzipped</i></td>
</tr>
</table>
@@ -183,7 +183,7 @@ <h2 id="styles">Object-Oriented and Functional Styles</h2>
<p>
<b>Arrays</b>
<br />
- <span class="methods"><a href="#first">first</a>, <a href="#last">last</a>,
+ <span class="methods"><a href="#first">first</a>, <a href="#rest">rest</a>, <a href="#last">last</a>,
<a href="#compact">compact</a>, <a href="#flatten">flatten</a>, <a href="#without">without</a>, <a href="#uniq">uniq</a>,
<a href="#intersect">intersect</a>, <a href="#zip">zip</a>, <a href="#indexOf">indexOf</a></span>,
<a href="#lastIndexOf">lastIndexOf</a></span>
@@ -454,15 +454,33 @@ <h2 id="styles">Object-Oriented and Functional Styles</h2>
</pre>
<h2>Array Functions</h2>
+
+ <p>
+ <i>Note: All array functions will also work on the <b>arguments</b> object.</i>
+ </p>
<p id="first">
- <b class="header">first</b><code>_.first(array)</code>
+ <b class="header">first</b><code>_.first(array, [n])</code>
+ <span class="alias">Alias: <b>head</b></span>
<br />
- Convenience to return the first element of an <b>array</b> (identical to <tt>array[0]</tt>).
+ Returns the first element of an <b>array</b>. Passing <b>n</b> will
+ return the first <b>n</b> elements of the array.
</p>
<pre>
-_.first([3, 2, 1]);
-=&gt; 3
+_.first([5, 4, 3, 2, 1]);
+=&gt; 5
+</pre>
+
+ <p id="rest">
+ <b class="header">rest</b><code>_.rest(array, [index])</code>
+ <span class="alias">Alias: <b>tail</b></span>
+ <br />
+ Returns the <b>rest</b> of the elements in an array. Pass an <b>index</b>
+ to return the values of the array from that index onward.
+ </p>
+ <pre>
+_.rest([5, 4, 3, 2, 1]);
+=&gt; [4, 3, 2, 1]
</pre>
<p id="last">
@@ -471,7 +489,7 @@ <h2 id="styles">Object-Oriented and Functional Styles</h2>
Returns the last element of an <b>array</b>.
</p>
<pre>
-_.last([3, 2, 1]);
+_.last([5, 4, 3, 2, 1]);
=&gt; 1
</pre>
@@ -913,6 +931,15 @@ <h2 id="styles">Object-Oriented and Functional Styles</h2>
<h2>Change Log</h2>
<p>
+ <b class="header">0.4.5</b><br />
+ Added <tt>rest</tt> for Arrays and arguments objects, and aliased
+ <tt>first</tt> as <tt>head</tt>, and <tt>rest</tt> as <tt>tail</tt>,
+ thanks to <a href="http://github.com/lukesutton/">Luke Sutton</a>'s patches.
+ Added tests ensuring that all Underscore Array functions also work on
+ <i>arguments</i> objects.
+ </p>
+
+ <p>
<b class="header">0.4.4</b><br />
Added <tt>isString</tt>, and <tt>isNumber</tt>, for consistency. Fixed
<tt>_.isEqual(NaN, NaN)</tt> to return <i>true</i> (which is debatable).
View
@@ -1,76 +1,89 @@
$(document).ready(function() {
-
+
module("Array-only functions (last, compact, uniq, and so on...)");
-
+
test("arrays: first", function() {
equals(_.first([1,2,3]), 1, 'can pull out the first element of an array');
equals(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"');
+ equals(_.first([1,2,3], 2).join(', '), '1, 2', 'can pass an index to first');
+ var result = (function(){ return _.first(arguments); })(4, 3, 2, 1);
+ equals(result, 4, 'works on an arguments object.');
});
-
+
+ test("arrays: rest", function() {
+ var numbers = [1, 2, 3, 4];
+ equals(_.rest(numbers).join(", "), "2, 3, 4", 'working rest()');
+ equals(_.rest(numbers, 2).join(', '), '3, 4', 'rest can take an index');
+ var result = (function(){ return _(arguments).tail(); })(1, 2, 3, 4);
+ equals(result.join(', '), '2, 3, 4', 'aliased as tail and works on arguments object');
+ });
+
test("arrays: last", function() {
equals(_.last([1,2,3]), 3, 'can pull out the last element of an array');
+ var result = (function(){ return _(arguments).last(); })(1, 2, 3, 4);
+ equals(result, 4, 'works on an arguments object');
});
-
+
test("arrays: compact", function() {
equals(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values');
+ var result = (function(){ return _(arguments).compact().length; })(0, 1, false, 2, false, 3);
+ equals(result, 3, 'works on an arguments object');
});
-
+
test("arrays: flatten", function() {
var list = [1, [2], [3, [[[4]]]]];
equals(_.flatten(list).join(', '), '1, 2, 3, 4', 'can flatten nested arrays');
+ var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]);
+ equals(result.join(', '), '1, 2, 3, 4', 'works on an arguments object');
});
-
+
test("arrays: without", function() {
var list = [1, 2, 1, 0, 3, 1, 4];
equals(_.without(list, 0, 1).join(', '), '2, 3, 4', 'can remove all instances of an object');
+ var result = (function(){ return _.without(arguments, 0, 1); })(1, 2, 1, 0, 3, 1, 4);
+ equals(result.join(', '), '2, 3, 4', 'works on an arguments object');
});
-
+
test("arrays: uniq", function() {
var list = [1, 2, 1, 3, 1, 4];
equals(_.uniq(list).join(', '), '1, 2, 3, 4', 'can find the unique values of an unsorted array');
-
+
var list = [1, 1, 1, 2, 2, 3];
equals(_.uniq(list, true).join(', '), '1, 2, 3', 'can find the unique values of a sorted array faster');
+
+ var result = (function(){ return _.uniq(arguments); })(1, 2, 1, 3, 1, 4);
+ equals(result.join(', '), '1, 2, 3, 4', 'works on an arguments object');
});
-
+
test("arrays: intersect", function() {
var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho'];
equals(_.intersect(stooges, leaders).join(''), 'moe', 'can take the set intersection of two arrays');
equals(_(stooges).intersect(leaders).join(''), 'moe', 'can perform an OO-style intersection');
+ var result = (function(){ return _.intersect(arguments, leaders); })('moe', 'curly', 'larry');
+ equals(result.join(''), 'moe', 'works an an arguments object');
});
-
+
test('arrays: zip', function() {
var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true];
var stooges = _.zip(names, ages, leaders);
equals(String(stooges), 'moe,30,true,larry,40,,curly,50,', 'zipped together arrays of different lengths');
});
-
+
test("arrays: indexOf", function() {
var numbers = [1, 2, 3];
numbers.indexOf = null;
equals(_.indexOf(numbers, 2), 1, 'can compute indexOf, even without the native function');
+ var result = (function(){ return _.indexOf(arguments, 2); })(1, 2, 3);
+ equals(result, 1, 'works on an arguments object');
});
-
+
test("arrays: lastIndexOf", function() {
var numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0];
numbers.lastIndexOf = null;
equals(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function');
equals(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element');
+ var result = (function(){ return _.lastIndexOf(arguments, 1); })(1, 0, 1, 0, 0, 1, 0, 0, 0);
+ equals(result, 5, 'works on an arguments object');
});
-
- test("arrays: tail", function() {
- var numbers = [1, 2, 3, 4];
- equals(_.tail(numbers).join(", "), "2, 3, 4");
- });
-
- test("arrays: init", function() {
- var numbers = [1, 2, 3, 4];
- equals(_.init(numbers).join(", "), "1, 2, 3");
- });
-
- test("arrays: reverse", function() {
- var numbers = [1, 2, 4, 6];
- equals(_.reverse(numbers).join(", "), "6, 4, 2, 1");
- });
-
+
});
View
@@ -31,12 +31,12 @@ $(document).ready(function() {
});
test("utility: functions", function() {
- var expected = ["all", "any", "bind", "bindAll", "breakLoop", "clone", "compact",
+ var expected = ["all", "any", "bind", "bindAll", "breakLoop", "clone", "compact",
"compose","defer", "delay", "detect", "each", "every", "extend", "filter", "first",
"flatten", "foldl", "foldr", "forEach", "functions", "head", "identity", "include",
- "indexOf", "init", "inject", "intersect", "invoke", "isArray", "isElement", "isEmpty", "isEqual",
+ "indexOf", "inject", "intersect", "invoke", "isArray", "isElement", "isEmpty", "isEqual",
"isFunction", "isNumber", "isString", "isUndefined", "keys", "last", "lastIndexOf", "map", "max",
- "methods", "min", "pluck", "reduce", "reduceRight", "reject", "reverse", "select",
+ "methods", "min", "pluck", "reduce", "reduceRight", "reject", "rest", "select",
"size", "some", "sortBy", "sortedIndex", "tail", "template", "toArray", "uniq",
"uniqueId", "values", "without", "wrap", "zip"];
ok(_(expected).isEqual(_.methods()), 'provides a sorted list of functions');
Oops, something went wrong.

0 comments on commit ae968a6

Please sign in to comment.