4
\$\begingroup\$

This function sorts an array and returns the unique items. I'm trying to get it down to a readable 5 lines of code. So far I've renamed the variable cursor variable and inlined the assignments. I'll appreciate fresh eyes.

Before

function uniques(array) {
    var result = [], val, ridx;
    outer:
    for (var i = 0, length = array.length; i < length; i++) {
        val = array[i];
        ridx = result.length;
        while (ridx--) {
          if (val === result[ridx]) continue outer;
        }
        result.push(val);
    }
    return result;
}

After

function uniques(array) {
    var result = [], val, cursor;
    outer:
        for (var i = 0, length = array.length; i < length; i++) {
        val = array[i], cursor = result.length;
        while (cursor--) {
          if (val === result[cursor]) continue outer;
        }
        result.push(val);
    }
    return result;
}
\$\endgroup\$
1
  • \$\begingroup\$ please change the title to what the code is doing. \$\endgroup\$ Nov 20, 2015 at 9:49

2 Answers 2

3
\$\begingroup\$

This function sorts an array and returns the unique items

  1. Remove duplicates from the array using Array#filter
  2. Sort the array using Array#sort

Code:

function uniques(arr) {
    // Remove the duplicate elements from the array
    return arr.filter(function (element, index, arr) {
        return arr.indexOf(element) === index;
    }).sort(function (a, b) {
        return a - b;
    });
}
\$\endgroup\$
2
\$\begingroup\$

This can be done as a 1 liner:

function uniques(arr) {
  return arr.sort().filter(function(x,i) { return x !== arr[i+1] });
}

All we're doing is sorting, then using filter to remove any element that is equal to its next adjacent element. Because the array is already sorted, it's guaranteed that duplicates will be next to one another.

Also note that this will run in O(n log n) time, and so will be faster than Tushar's answer, which filters first and then sorts -- the filtering step there will be O(n^2) because of the call to indexOf.

Finally, the above solution mutates the orginal array. If you'd like avoid that, simply add in a slice:

function uniques(arr) {
  return arr.slice(0).sort().filter(function(x,i) { return x !== arr[i+1] });
}
\$\endgroup\$
3
  • \$\begingroup\$ Filtering first will lower the number of operations to sort the array, thus improving the performance a bit \$\endgroup\$
    – Tushar
    Nov 22, 2015 at 5:58
  • \$\begingroup\$ That doesn't matter, because sorting is O(nlogn) and filtering the way you are doing it is O(n^2). The largest term will dominate and your method will be much slower for large n. \$\endgroup\$
    – Jonah
    Nov 22, 2015 at 6:15
  • \$\begingroup\$ you just blew my mind! \$\endgroup\$
    – Rob
    Nov 22, 2015 at 18:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.