diff --git a/test/arrays.js b/test/arrays.js index 54cd9f8d2..ff430648d 100644 --- a/test/arrays.js +++ b/test/arrays.js @@ -89,6 +89,28 @@ $(document).ready(function() { var result = (function(){ return _.uniq(arguments); })(1, 2, 1, 3, 1, 4); equal(result.join(', '), '1, 2, 3, 4', 'works on an arguments object'); + + var list = []; + list[2] = list[3] = null; + list[8] = 2; + list[10] = 2; + list[11] = 5; + list[14] = 5; + list[16] = 8; + list[19] = 8; + list[26] = list[29] = undefined; + list[33] = "hi"; + + var result = _.uniq(list, true); + if (0 in [undefined]) { + // According to the JScript ES 3 spec, section 2.1.26, JScript 5.x (IE <= + // 8) treats `undefined` elements in arrays as elisions. + deepEqual(result, [null, 2, 5, 8, undefined, "hi"], "Works with sorted sparse arrays"); + equal(result.length, 6, "The resulting array should not be sparse"); + } else { + deepEqual(result, [null, 2, 5, 8, "hi"], "Works with sorted sparse arrays where `undefined` elements are elided"); + equal(result.length, 5, "The resulting array should not be sparse"); + } }); test("arrays: intersection", function() { diff --git a/underscore.js b/underscore.js index a283e55ff..88da6e1d8 100644 --- a/underscore.js +++ b/underscore.js @@ -372,15 +372,17 @@ // Aliased as `unique`. _.uniq = _.unique = function(array, isSorted, iterator) { var initial = iterator ? _.map(array, iterator) : array; - var result = []; - _.reduce(initial, function(memo, el, i) { - if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) { - memo[memo.length] = el; - result[result.length] = array[i]; + var results = []; + // The `isSorted` flag is irrelevant if the array only contains two elements. + if (array.length < 3) isSorted = true; + _.reduce(initial, function (memo, value, index) { + if (isSorted ? _.last(memo) !== value || !memo.length : !_.include(memo, value)) { + memo.push(value); + results.push(array[index]); } return memo; }, []); - return result; + return results; }; // Produce an array that contains the union: each distinct element from all of