Yes, there is.
Your current solution has a O(n²) runtime complexity which is worse then necessary.
By sorting the array and then only marching once, comparing only neighboring elements, extracting unique elements costs only O(n * log(n)).
var arr=[10,20,30,20,40,10];
function uniqueBySorting(array) {
var sortedArray = array.slice().sort(function(a, b) {
return a > b ? 1 : 0;
});
var result = [];
result.push(sortedArray[0]);
for (var i = 1, length = sortedArray.length; i < length; i++) {
if (sortedArray[i] !== sortedArray[i - 1]) {
result.push(sortedArray[i]);
}
}
return result;
}
console.log(uniqueBySorting(arr));
However, that comes at the cost of loosing the sort order, which might not be desired. If the sort order matters, use a hashed set for remembering which elements you already encountered instead of the inner loop, so you finally end up with a O(n) complexity.
var arr=[10,20,30,20,40,10];
function uniqueWithObjectHashSet(array) {
var hashSet = {}, result = [];
array.forEach(function(element) {
if (!element in hashSet) {
newarr.push(element);
hashSet[element] = true;
}
});
return result;
}
console.log(uniqueWithObjectHashSet(arr));
Inserting elements into a hash set and looking them up requires only constant time, opposed to the linear time required for iterating over the target array.
Technically JS does not have any native hashset implementation, but lucky for you most JS engines tend to implement objects as hashsets internally (unless the JIT can identify properties with constant names), so you can abuse that behavior.
See Hashset in Javascript for more information on the last point.
Comparison of the HashSet implementation (including @hindmost's variant) to previous solutions: http://jsperf.com/cr-57581/7
Not surprising, all versions with nested loops are left far behind. As of April 2015, the hashSet version using Array.prototype.forEach
is by far the fastest algorithm in Firefox. In Chrome with V8 however, the sorting based solution is much faster, most likely due to a more efficient implementation of Array.prototype.sort
.