Skip to content

Commit

Permalink
Rework of #68, to use a flag to indexOf, instead of a separate function.
Browse files Browse the repository at this point in the history
  • Loading branch information
jashkenas committed Dec 17, 2010
1 parent 8c2570b commit d2d6cfe
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 41 deletions.
20 changes: 4 additions & 16 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ <h2>Table of Contents</h2>
<a href="#invoke">invoke</a>, <a href="#pluck">pluck</a>,
<a href="#max">max</a>, <a href="#min">min</a>,
<a href="#sortBy">sortBy</a>, <a href="#sortedIndex">sortedIndex</a>,
<a href="#sortedIndexOf">sortedIndexOf</a>,
<a href="#toArray">toArray</a>, <a href="#size">size</a></span>
</p>

Expand Down Expand Up @@ -453,19 +452,6 @@ <h2>Collection Functions (Arrays or Objects)</h2>
<pre>
_.sortedIndex([10, 20, 30, 40, 50], 35);
=&gt; 3
</pre>

<p id="sortedIndexOf">
<b class="header">sortedIndexOf</b><code>_.sortedIndexOf(list, value)</code>
<br />
Not to be confused with <tt>_.sortedIndex</tt>, this method works like
the native <tt>indexOf</tt>, but uses binary search to efficiently
find the value in large, already-sorted arrays. Returns <tt>-1</tt>
if the value is not present.
</p>
<pre>
_.sortedIndex([10, 20, 30, 40, 50], 30);
=&gt; 2
</pre>

<p id="toArray">
Expand Down Expand Up @@ -599,11 +585,13 @@ <h2>Array Functions</h2>
</pre>

<p id="indexOf">
<b class="header">indexOf</b><code>_.indexOf(array, value)</code>
<b class="header">indexOf</b><code>_.indexOf(array, value, [isSorted])</code>
<br />
Returns the index at which <b>value</b> can be found in the <b>array</b>,
or <i>-1</i> if value is not present in the <b>array</b>. Uses the native
<b>indexOf</b> function unless it's missing.
<b>indexOf</b> function unless it's missing. If you're working with a
large array, and you know that the array is already sorted, pass <tt>true</tt>
for <b>isSorted</b> to use a faster binary search.
</p>
<pre>
_.indexOf([1, 2, 3], 2);
Expand Down
12 changes: 12 additions & 0 deletions test/arrays.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@ $(document).ready(function() {
var result = (function(){ return _.indexOf(arguments, 2); })(1, 2, 3);
equals(result, 1, 'works on an arguments object');
equals(_.indexOf(null, 2), -1, 'handles nulls properly');

var numbers = [10, 20, 30, 40, 50], num = 35;
var index = _.indexOf(numbers, num, true);
equals(index, -1, '35 is not in the list');

numbers = [10, 20, 30, 40, 50]; num = 40;
index = _.indexOf(numbers, num, true);
equals(index, 3, '40 is in the list');

numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40;
index = _.indexOf(numbers, num, true);
equals(index, 1, '40 is in the list');
});

test("arrays: lastIndexOf", function() {
Expand Down
14 changes: 0 additions & 14 deletions test/collections.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,20 +185,6 @@ $(document).ready(function() {
equals(index, 3, '35 should be inserted at index 3');
});

test('collections: sortedIndexOf', function() {
var numbers = [10, 20, 30, 40, 50], num = 35;
var index = _.sortedIndexOf(numbers, num);
equals(index, -1, '35 is not in the list');

numbers = [10, 20, 30, 40, 50]; num = 40;
index = _.sortedIndexOf(numbers, num);
equals(index, 3, '40 is in the list');

numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40;
index = _.sortedIndexOf(numbers, num);
equals(index, 1, '40 is in the list');
});

test('collections: toArray', function() {
ok(!_.isArray(arguments), 'arguments object is not an array');
ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array');
Expand Down
18 changes: 7 additions & 11 deletions underscore.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,6 @@

// Use a comparator function to figure out at what index an object should
// be inserted so as to maintain order. Uses binary search.
// Unlike `_.sortedIndexOf`, this function returns the array at which an
// element *should* be inserted, not where it actually is.
_.sortedIndex = function(array, obj, iterator) {
iterator = iterator || _.identity;
var low = 0, high = array.length;
Expand All @@ -266,14 +264,6 @@
return low;
};

// Similar to native `indexOf`, but assumes that the array being searched
// is already sorted, giving much faster performance on large arrays.
// Not to be confused with `_.sortedIndex`.
_.sortedIndexOf = function(array, obj) {
var i = _.sortedIndex(array, obj);
return array[i] === obj ? i : -1;
};

// Safely convert anything iterable into a real, live array.
_.toArray = function(iterable) {
if (!iterable) return [];
Expand Down Expand Up @@ -366,8 +356,14 @@
// we need this function. Return the position of the first occurrence of an
// item in an array, or -1 if the item is not included in the array.
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
_.indexOf = function(array, item) {
// If the array is large and already in sort order, pass `true`
// for **isSorted** to use binary search.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
if (isSorted) {
var i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
for (var i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
return -1;
Expand Down

0 comments on commit d2d6cfe

Please sign in to comment.