Как создать список уникальных элементов в JavaScript?

В моей функции уменьшения CouchDB мне нужно уменьшить список элементов до уникальных.

Примечание: в этом случае это нормально, чтобы иметь список, это будет небольшое количество элементов строкового типа.

Мой текущий способ - установить ключи объекта, а затем вернуть ключи этого объекта так как место, где код не может использовать такие вещи, как _.uniq, например.

Я хотел бы найти более элегантный способ записать это, чем это.

function(keys, values, rereduce) {
  // values is a Array of Arrays
  values = Array.concat.apply(null, values);
  var uniq = {};
  values.forEach(function(item) { uniq[item] = true; });
  return Object.keys(uniq);
}

Ответ 1

Обычно подход, который вы использовали, является хорошей идеей. Но я мог бы предложить решение, которое сделает алгоритм намного быстрее.

function unique(arr) {
    var u = {}, a = [];
    for(var i = 0, l = arr.length; i < l; ++i){
        if(!u.hasOwnProperty(arr[i])) {
            a.push(arr[i]);
            u[arr[i]] = 1;
        }
    }
    return a;
}

Как вы можете видеть, здесь есть только один цикл.

Я сделал пример, который тестирует ваши и мои решения. Попробуйте сыграть с ним.

Ответ 2

Альтернативой, подходящей для небольших списков, является обезьяна подхода командной строки Unix sort | uniq:

    function unique(a) {
        return a.sort().filter(function(value, index, array) {
            return (index === 0) || (value !== array[index-1]);
        });
    }

Эта функция сортирует аргумент и затем фильтрует результат, чтобы опустить любые элементы, которые соответствуют их предшественнику.

Ключ-подход хорош и будет иметь лучшие характеристики производительности для большого количества элементов (O (n) для вставки n элементов в хэш-таблицу по сравнению с O (n log n) для сортировки массива). Однако это маловероятно, чтобы это было заметно в небольших списках. Более того, с этой версией вы могли бы изменить ее, чтобы использовать другую функцию сортировки или равенства, если это необходимо; с хэш-ключами вы застряли в концепции JavaScripts о равенстве ключей.

Ответ 3

Лучший метод, похоже, использует ES6 и Set. Одиночная линия и быстрее *, чем выше, согласно скрипке

    
const myList = [1,4,5,1,2,4,5,6,7];
const unique = [...new Set(myList)];
    
console.log(unique);

Ответ 4

Это должно работать с чем угодно, а не только с строк:

export const getUniqueList =  (a: Array<any>) : Array<any> => {

  const set = new Set<any>();

  for(let v of a){
      set.add(v);
  }

  return Array.from(set);

};

вышесказанное можно просто свести к:

export const getUniqueValues = (a: Array<any>) => {
   return Array.from(new Set(a));
};

:)

Ответ 5

Это старый вопрос, я знаю. Однако он находится на вершине некоторых поисковых запросов Google, поэтому я хотел добавить, что вы можете комбинировать ответы от @RobHague и @EugeneNaydenov, используя следующее:

function unique(arr) {
  const u = {};
  return arr.filter((v) => {
    return u[v] = !u.hasOwnProperty(v);
  });
};

Вы также можете игнорировать неопределенные значения (часто удобные), добавляя:

function unique(arr) {
  const u = {};
  return arr.filter((v) => {
    return u[v] = (v !== undefined && !u.hasOwnProperty(v));
  });
};

Вы можете играть с этим решением здесь: https://jsfiddle.net/s8d14v5n/

Ответ 6

Использование Object.keys даст вам строки, если вы поместите целые аргументы (uniq ([1,2,3]) = > ['1', '2', '3']. Здесь один с Array.reduce

function uniq(list) {
    return list.reduce((acc, d) => acc.includes(d) ? acc : acc.concat(d), []);
}

Ответ 7

как насчет

    function unique(list) {
      for (i = 0; i<list.length; i++) {
        for (j=i+1; j<list.length; j++) {
          if (list[i] == list[j]) {
            list.splice(j, 1);
          }
        }
      }
    }