Separate _.uniq isSorted logic to a helper

This commit is contained in:
megawac
2014-07-13 16:55:46 -04:00
committed by John-David Dalton
parent 6f937e8958
commit 95ba6bf040
2 changed files with 28 additions and 18 deletions

View File

@@ -2380,17 +2380,35 @@
return high;
}
/**
* The implementation of `_.uniq` optimized for sorted arrays
*
* @private
* @param {Array} array The array to inspect.
* @returns {Array} Returns the new duplicate-value-free array.
*/
function sortedUniq(array) {
var result = [],
index = -1,
length = array ? array.length : 0;
while (++index < length) {
if (index + 1 > length || array[index] !== array[index + 1]) {
result.push(array[index]);
}
}
return result;
};
/**
* The base implementation of `_.uniq` without support for callback shorthands
* and `this` binding.
*
* @private
* @param {Array} array The array to inspect.
* @param {boolean} [isSorted=false] Specify the array is sorted.
* @param {Function} [iterator] The function called per iteration.
* @returns {Array} Returns the new duplicate-value-free array.
*/
function baseUniq(array, isSorted, iterator) {
function baseUniq(array, iterator) {
var length = array ? array.length : 0;
if (!length) {
return [];
@@ -2402,12 +2420,11 @@
isCommon = prereq && !isLarge,
result = [];
isSorted = prereq && isSorted;
if (isLarge) {
var seen = createCache();
indexOf = cacheIndexOf;
} else {
seen = (iterator && !isSorted) ? [] : result;
seen = iterator ? [] : result;
}
outer:
while (++index < length) {
@@ -2426,12 +2443,6 @@
}
result.push(value);
}
else if (isSorted) {
if (!index || seen !== computed) {
seen = computed;
result.push(value);
}
}
else if (indexOf(seen, computed) < 0) {
if (iterator || isLarge) {
seen.push(computed);
@@ -4095,26 +4106,23 @@
* // => [{ 'x': 1 }, { 'x': 2 }]
*/
function uniq(array, isSorted, iterator, thisArg) {
var length = array ? array.length : 0;
if (!length) {
return [];
}
// juggle arguments
var type = typeof isSorted;
if (type != 'boolean' && isSorted != null) {
thisArg = iterator;
iterator = isSorted;
isSorted = false;
// enables use as a callback for functions like `_.map`
if ((type == 'number' || type == 'string') && thisArg && thisArg[iterator] === array) {
iterator = null;
}
} else if (isSorted && getIndexOf() == baseIndexOf) {
return sortedUniq(array);
}
if (iterator != null) {
iterator = getCallback(iterator, thisArg, 3);
}
return baseUniq(array, isSorted, iterator);
return baseUniq(array, iterator);
}
/**

View File

@@ -10683,9 +10683,11 @@
deepEqual(_.uniq(objects), objects);
});
test('should work with `isSorted`', 1, function() {
var array = [1, 1, 2, 2, 3];
test('should work with `isSorted`', 4, function() {
deepEqual(_.uniq([1, 1, 2, 2, 3], true), [1, 2, 3]);
deepEqual(_.uniq(_.range(100), true), _.range(100));
deepEqual(_.uniq(_.times(100, _.constant(undefined))), [undefined]);
deepEqual(_.uniq([1, 2, 3, 3, 3, 3, 3]), [1, 2, 3]);
});
test('should work with a callback', 1, function() {