Skip to content

Commit

Permalink
Add _.sortedLastIndex
Browse files Browse the repository at this point in the history
  • Loading branch information
jridgewell committed Mar 13, 2015
1 parent f77e099 commit 97a7d25
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 12 deletions.
30 changes: 28 additions & 2 deletions test/arrays.js
Expand Up @@ -112,9 +112,9 @@
});

test('sortedIndex', function() {
var numbers = [10, 20, 30, 40, 50], num = 35;
var numbers = [10, 20, 30, 30, 30, 40, 50], num = 35;
var indexForNum = _.sortedIndex(numbers, num);
equal(indexForNum, 3, '35 should be inserted at index 3');
equal(indexForNum, 5, '35 should be inserted at index 5');

var indexFor30 = _.sortedIndex(numbers, 30);
equal(indexFor30, 2, '30 should be inserted at index 2');
Expand All @@ -137,6 +137,32 @@
equal(_.sortedIndex(array, 2147483648), 2147483648, 'should work with large indexes');
});

test('sortedLastIndex', function() {
var numbers = [10, 20, 30, 30, 30, 40, 50], num = 35;
var indexForNum = _.sortedLastIndex(numbers, num);
equal(indexForNum, 5, '35 should be inserted at index 5');

var indexFor30 = _.sortedLastIndex(numbers, 30);
equal(indexFor30, 5, '30 should be inserted at index 5');

var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}];
var iterator = function(obj){ return obj.x; };
strictEqual(_.sortedLastIndex(objects, {x: 25}, iterator), 2);
strictEqual(_.sortedLastIndex(objects, {x: 35}, 'x'), 3);

var context = {1: 2, 2: 3, 3: 4};
iterator = function(obj){ return this[obj]; };
strictEqual(_.sortedLastIndex([1, 3], 2, iterator, context), 1);

var values = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647];
var array = Array(Math.pow(2, 32) - 1);
var length = values.length;
while (length--) {
array[values[length]] = values[length];
}
equal(_.sortedLastIndex(array, 2147483648), 2147483648, 'should work with large indexes');
});

test('uniq', function() {
var list = [1, 2, 1, 3, 1, 4];
deepEqual(_.uniq(list), [1, 2, 3, 4], 'can find the unique values of an unsorted array');
Expand Down
29 changes: 19 additions & 10 deletions underscore.js
Expand Up @@ -655,16 +655,25 @@

// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iteratee, context) {
iteratee = cb(iteratee, context, 1);
var value = iteratee(obj);
var low = 0, high = array.length;
while (low < high) {
var mid = Math.floor((low + high) / 2);
if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
}
return low;
};
function createSortedIndexFinder(lessThan) {
return function(array, obj, iteratee, context) {
iteratee = cb(iteratee, context, 1);
var value = iteratee(obj);
var low = 0, high = array.length;
while (low < high) {
var mid = Math.floor((low + high) / 2);
var computed = iteratee(array[mid]);
if ((lessThan && computed < value) || (!lessThan && computed <= value)) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
};
}
_.sortedIndex = createSortedIndexFinder(true);
_.sortedLastIndex = createSortedIndexFinder(false);

// Generate an integer Array containing an arithmetic progression. A port of
// the native Python `range()` function. See
Expand Down

0 comments on commit 97a7d25

Please sign in to comment.