Skip to content

Commit e6f241f

Browse files
Fix for the issue angular-ui#87 plus unit tests
1 parent c733c83 commit e6f241f

File tree

2 files changed

+85
-24
lines changed

2 files changed

+85
-24
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
describe('unique', function() {
2+
var uniqueFilter;
3+
4+
beforeEach(module('ui.filters'));
5+
beforeEach(inject(function($filter) {
6+
uniqueFilter = $filter('unique');
7+
}));
8+
9+
it('should return unique entries based on object equality', function () {
10+
var arrayToFilter = [{key: 'value'}, {key: 'value2'}, {key: 'value'}];
11+
expect(uniqueFilter(arrayToFilter)).toEqual([{key: 'value'}, {key: 'value2'}]);
12+
});
13+
14+
it('should return unique entries based on object equality for complex objects', function () {
15+
var arrayToFilter = [{key: 'value', other: 'other1'}, {key: 'value2', other: 'other2'}, {other: 'other1', key: 'value'}];
16+
expect(uniqueFilter(arrayToFilter)).toEqual([{key: 'value', other: 'other1'}, {key: 'value2', other: 'other2'}]);
17+
});
18+
19+
it('should return unique entries based on the key provided', function () {
20+
var arrayToFilter = [{key: 'value'}, {key: 'value2'}, {key: 'value'}];
21+
expect(uniqueFilter(arrayToFilter, 'key')).toEqual([{key: 'value'}, {key: 'value2'}]);
22+
});
23+
24+
it('should return unique entries based on the key provided for complex objects', function () {
25+
var arrayToFilter = [{key: 'value', other: 'other1'}, {key: 'value2', other: 'other2'}, {key: 'value', other: 'other3'}];
26+
expect(uniqueFilter(arrayToFilter, 'key')).toEqual([{ key : 'value', other : 'other1' }, { key : 'value2', other : 'other2' }]);
27+
});
28+
29+
it('should return unique primitives in arrays', function() {
30+
expect(uniqueFilter([1,2,1,3])).toEqual([1,2,3]);
31+
});
32+
33+
it('should work correctly for arrays of mixed elements and object equality', function () {
34+
expect(uniqueFilter([1,{key:'value'},1,{key:'value'},2,"string",3])).toEqual([1,{key:'value'},2,"string",3]);
35+
});
36+
37+
it('should work correctly for arrays of mixed elements and a key specified', function () {
38+
expect(uniqueFilter([1,{key:'value'},1,{key:'value'},2,"string",3],'key')).toEqual([1,{key:'value'},2,"string",3]);
39+
});
40+
41+
it('should return unmodified object if not array', function() {
42+
expect(uniqueFilter('string','someKey')).toEqual('string');
43+
});
44+
45+
it('should return unmodified array if provided key === false', function() {
46+
var arrayToFilter = [{key: 'value1'}, {key: 'value2'}];
47+
expect(uniqueFilter(arrayToFilter, false)).toEqual(arrayToFilter);
48+
});
49+
50+
})

modules/filters/unique/unique.js

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,41 @@
1-
21
/**
32
* Filters out all duplicate items from an array by checking the specified key
43
* @param [key] {string} the name of the attribute of each object to compare for uniqueness
5-
if the key is empty, the entire object will be compared
6-
if the key === false then no filtering will be performed
4+
if the key is empty, the entire object will be compared
5+
if the key === false then no filtering will be performed
76
* @return {array}
87
*/
9-
angular.module('ui.filters').filter('unique', function() {
10-
return function(items, key) {
11-
if (key && angular.isArray(items)) {
12-
var hashCheck = {},
13-
newItems = [];
14-
angular.forEach(items, function(item, key){
15-
var value;
16-
if (angular.isString(key)) {
17-
value = item[key];
18-
} else {
19-
value = item;
20-
}
21-
if (hashCheck[value] === undefined) {
22-
hashCheck[value] = true;
23-
newItems.push(item);
24-
}
25-
});
26-
items = newItems;
27-
}
28-
return items;
29-
};
8+
angular.module('ui.filters').filter('unique', function () {
9+
10+
return function (items, filterOn) {
11+
12+
if (filterOn === false || !angular.isArray(items)) {
13+
return items;
14+
}
15+
16+
var newItems = [];
17+
var extractValueToCompare = function (item) {
18+
if (angular.isObject(item) && filterOn) {
19+
return item[filterOn];
20+
} else {
21+
return item;
22+
}
23+
};
24+
25+
angular.forEach(items, function (item) {
26+
var valueToCheck, isDuplicate = false, i=0;
27+
28+
for (; i < newItems.length; i++) {
29+
if (angular.equals(extractValueToCompare(newItems[i]), extractValueToCompare(item))) {
30+
isDuplicate = true;
31+
break;
32+
}
33+
}
34+
if (!isDuplicate) {
35+
newItems.push(item);
36+
}
37+
});
38+
39+
return newItems;
40+
};
3041
});

0 commit comments

Comments
 (0)