Skip to content

Commit

Permalink
adding includeWith, and uniqeWith functions
Browse files Browse the repository at this point in the history
this allows for using custom matcher function for comparison
defaults to _.isEqual jashkenas#2311
  • Loading branch information
dperrymorrow committed Nov 30, 2015
1 parent 19b1e46 commit de6be19
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 0 deletions.
29 changes: 29 additions & 0 deletions test/arrays.js
Expand Up @@ -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');
Expand Down
25 changes: 25 additions & 0 deletions test/collections.js
Expand Up @@ -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');
});
Expand Down
23 changes: 23 additions & 0 deletions underscore.js
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit de6be19

Please sign in to comment.