From 8c2570b0baef1ba3fe9d9983e4b4d2b27d268b86 Mon Sep 17 00:00:00 2001
From: Jeremy Ashkenas
_.sortedIndex(list, value, [iterator])
_.sortedIndex([10, 20, 30, 40, 50], 35); => 3 ++ +
+ sortedIndexOf_.sortedIndexOf(list, value)
+
+ Not to be confused with _.sortedIndex, this method works like
+ the native indexOf, but uses binary search to efficiently
+ find the value in large, already-sorted arrays. Returns -1
+ if the value is not present.
+
+_.sortedIndex([10, 20, 30, 40, 50], 30); +=> 2
diff --git a/test/collections.js b/test/collections.js index 442b205f1..6c0e8830c 100644 --- a/test/collections.js +++ b/test/collections.js @@ -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'); diff --git a/underscore.js b/underscore.js index 6cb2527dd..4d0851935 100644 --- a/underscore.js +++ b/underscore.js @@ -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; @@ -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 [];