diff --git a/test/arrays.js b/test/arrays.js index ad9100c66..86b706e8a 100644 --- a/test/arrays.js +++ b/test/arrays.js @@ -193,6 +193,35 @@ assert.strictEqual(_.unique, _.uniq, 'is an alias for uniq'); }); + test('uniqueWithAlias', function (assert) { + assert.strictEqual(_.uniqueWith, _.uniqWith, 'is an alias for uniqWith'); + }); + + test('uniqWith', function(assert) { + var list = [1, 2, 1, 3, 1, 4], + kittens = [ + {kitten: 'Celery', cuteness: 8}, + {kitten: 'Juniper', cuteness: 10}, + {kitten: 'Juniper', cuteness: 10}, + {kitten: 'Spottis', cuteness: 10}, + {kitten: 'Stripes', cuteness: 11} + ], + uniqeKittens = [ + {kitten: 'Celery', cuteness: 8}, + {kitten: 'Juniper', cuteness: 10}, + {kitten: 'Spottis', cuteness: 10}, + {kitten: 'Stripes', cuteness: 11} + ], + byCuteness = function (a, b) { + return a.cuteness === b.cuteness; + } + + assert.deepEqual(_.uniqWith(list), [1, 2, 3, 4], 'can find the unique values from a non object array'); + assert.deepEqual(_.uniqWith(kittens, _.isEqual), uniqeKittens, 'finds unique objects using _.isEqual'); + assert.deepEqual(_.uniqWith(kittens), uniqeKittens, 'defaults to _.isEqual if nothing passed'); + assert.deepEqual(_.pluck(_.uniqWith(kittens, byCuteness), 'cuteness'), [8, 10, 11], 'returns all, if comparator only looks at name'); + }); + test('intersection', function(assert) { var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho']; assert.deepEqual(_.intersection(stooges, leaders), ['moe'], 'can take the set intersection of two arrays'); diff --git a/test/collections.js b/test/collections.js index 721f4acb7..b546329d7 100644 --- a/test/collections.js +++ b/test/collections.js @@ -430,6 +430,31 @@ assert.ok(_.every([1, 2, 3], _.partial(_.includes, numbers)), 'fromIndex is guarded'); }); + test('includeWithAlias', function(assert) { + assert.strictEqual(_.includeWith, _.includesWith, 'is an alias for containsWith'); + assert.strictEqual(_.includeWith, _.containsWith, 'is an alias for includeWith'); + }); + + test('includeWith', function(assert) { + + var list = [1, 2, 1, 3, 1, 4]; + var kittens = [ + {kitten: 'Celery', cuteness: 8}, + {kitten: 'Juniper', cuteness: 10}, + {kitten: 'Spottis', cuteness: 10} + ]; + + var checkCute = function(a, b) { + return a.cuteness == 8; + } + + assert.strictEqual(_.includeWith(list, 4), true, 'should find the item in the list'); + assert.strictEqual(_.includeWith(kittens, {cuteness: 8}, checkCute), true, 'should use the method passed for comparison'); + assert.strictEqual(_.includeWith(kittens, {kitten: 'Juniper', cuteness: 8}, _.isEqual), false, 'should not find as cuteness does not match'); + assert.strictEqual(_.includeWith(kittens, {kitten: 'Juniper', cuteness: 10}, _.isEqual), true, 'should find the obj as cuteness matches'); + assert.strictEqual(_.includeWith(kittens, {kitten: 'Juniper', cuteness: 10}), true, 'should use _.isEqual by default'); + }); + test('include', function(assert) { assert.strictEqual(_.include, _.includes, 'is an alias for includes'); }); diff --git a/underscore.js b/underscore.js index 682cdf647..ed481cde6 100644 --- a/underscore.js +++ b/underscore.js @@ -278,6 +278,15 @@ return _.indexOf(obj, item, fromIndex) >= 0; }; + _.containsWith = _.includesWith = _.includeWith = function(array, item, predicate) { + predicate = _.isFunction(predicate) ? predicate : _.isEqual; + for (var i = 0, length = getLength(array); i < length; i++) { + if (predicate(array[i], item)) + return true; + } + return false; + }; + // Invoke a method (with arguments) on every item in a collection. _.invoke = restArgs(function(obj, method, args) { var isFunc = _.isFunction(method); @@ -560,6 +569,20 @@ return result; }; + // Produce a duplicate-free version of the array using the passed function for comparison rather than === + // comparator defaults to _.isEqual for comparison if omitted + _.uniqueWith = _.uniqWith = function(array, predicate) { + var result = [], item; + predicate = _.isFunction(predicate) ? predicate : _.isEqual; + + for (var i = 0, length = getLength(array); i < length; i++) { + item = array[i]; + if (!_.containsWith(result, item, predicate)) + result.push(item); + } + return result; + }; + // Produce an array that contains the union: each distinct element from all of // the passed-in arrays. _.union = restArgs(function(arrays) {