Skip to content

Commit

Permalink
Issue jashkenas#68. Adding _.sortedIndexOf
Browse files Browse the repository at this point in the history
  • Loading branch information
jashkenas committed Dec 17, 2010
1 parent 3a113d2 commit 8c2570b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 1 deletion.
16 changes: 15 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ <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 @@ -445,13 +446,26 @@ <h2>Collection Functions (Arrays or Objects)</h2>
<b class="header">sortedIndex</b><code>_.sortedIndex(list, value, [iterator])</code>
<br />
Uses a binary search to determine the index at which the <b>value</b>
should be inserted into the <b>list</b> in order to maintain the <b>list</b>'s
<i>should</i> be inserted into the <b>list</b> in order to maintain the <b>list</b>'s
sorted order. If an <b>iterator</b> is passed, it will be used to compute
the sort ranking of each value.
</p>
<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
14 changes: 14 additions & 0 deletions test/collections.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,20 @@ $(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
10 changes: 10 additions & 0 deletions underscore.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@

// 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 @@ -264,6 +266,14 @@
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

0 comments on commit 8c2570b

Please sign in to comment.