0

What is the way of producing an array of unique values out of another array using functional programming in JavaScript?

This should do: toUnique([1,1,2,3,4,4]) => [1,2,3,4]

Roman Liutikov
  • 1,338
  • 10
  • 17

3 Answers3

2

Take a look at the uniq function of the Ramda functional javascript libriary.

R.uniq([1, 1, 2, 1]); //=> [1, 2]
R.uniq([{}, {}]);     //=> [{}, {}]
R.uniq([1, '1']);     //=> [1, '1']

You can use the function from libriary or check the source code...

function uniq(list) {
    var idx = -1, len = list.length;
    var result = [], item;
    while (++idx < len) {
        item = list[idx];
        if (!_contains(item, result)) {
            result[result.length] = item;
        }
    }
    return result;
};
Max Brodin
  • 3,903
  • 1
  • 14
  • 23
1

Well, if you are not worried about the performance, I would use Array.prototype.filter and Array.prototype.indexOf, like this

function toUnique(array) {
    return array.filter(function(currentItem, index) {
        return (index === array.indexOf(currentItem));
    });
}

console.log(toUnique([1, 1, 2, 3, 4, 4]));
# [ 1, 2, 3, 4 ]

If you can use any other libraries, you can use lodash's uniq function, like this

_.uniq([1, 1, 2, 3, 4, 4]);
// → [1, 2, 3, 4]

It can also take advantage of the fact that the input array is already sorted. So, you might want to invoke it like this

_.uniq([1, 1, 2, 3, 4, 4], true);
// → [1, 2, 3, 4]
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
1

This has been asked and answered 1000 times before, but since you're asking for a functional programming solution, here you go:

head  = function(ls)  { return ls[0] };
tail  = function(ls)  { return ls.slice(1) };
empty = function(ls)  { return ls.length == 0 };
cons  = function(a, b) { return [a].concat(b) };

has = function(x, ls) {
    return empty(ls) ? false : head(ls) == x || has(x, tail(ls));
};

_uniq = function(ls, seen) {
    return empty(ls) ? [] :
        has(head(ls), seen) ?
            _uniq(tail(ls), seen) :
            cons(head(ls),
                _uniq(tail(ls),
                    cons(head(ls), seen)));
};

uniq = function(ls) {
    return _uniq(ls, []);
};

console.log(uniq([1,1,2,3,1,2,5])); // [1,2,3,5]

This is pure functional solution, as requested (in fact, a straight port of nub). For a practical one, consider one of the answers over here.

Community
  • 1
  • 1
georg
  • 211,518
  • 52
  • 313
  • 390