Как создать список уникальных элементов в 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);
}
}
}
}