Лучший способ удалить дублирующиеся строки в массиве

Нам удалось создать приведенный ниже скрипт для удаления любых дублирующихся строк из массива. Тем не менее, важно, чтобы мы сохранили порядок массива, когда угловые петли проходят по ним при ng-повторении. Кроме того, мы хотим, чтобы оставшиеся элементы сохранили тот же индекс.

scope.feedback = _.map(_.pluck(item.possibleAnswers, 'feedback'), function (element, index, collection) {
    return collection.slice(0, index).indexOf(element) === -1 ? element : '';
});

Этот код выше работает, однако мы считаем, что должно быть более простое решение нашей проблемы, чем это. Кто-нибудь еще сталкивался с подобной проблемой и придумал лучшее решение?

7 ответов

Решение

Вариант с уменьшением https://jsfiddle.net/58z7nrfy/1/

var a = [1,2,3,1,2,3,2,2,3,4,5,5,12,1,23,4,1];

var b = a.reduce(function(p,c,i,a){
  if (p.indexOf(c) == -1) p.push(c);
  else p.push('')
  return p;
}, [])
console.log(b)

[1, 2, 3, "", "", "", "", "", "", 4, 5, "", 12, "", 23, "", ""]

Если целевые браузеры поддерживают оператор распространения, попробуйте в консоли:

[...new Set(['3','1','1','5'])]
// ['3','1','5']

Или, если браузер поддерживает Array.from, вы также можете написать:

Array.from(new Set(['3','1','1','5']))
// ['3','1','5']

Помимо упомянутых ответов, вы также можете использовать функцию объединения lodash:

let duplicates = ['Hello', 'Hi', 'Hello'];
let uniques = _.union(duplicates);

Уникальности будут: ["Привет", "Привет"]

Вы могли бы использовать Map, который является типом доказать и предотвращает повторение снова и снова с Array#indexOf,

var a = [1, 2, 3, 1, 2, 3, 2, 2, 3, 4, 5, 5, 12, 1, 23, 4, 1, '23'],
    filtered = a.filter(function (a) {
        if (!this.has(a)) {
            this.set(a, true);
            return true;
        }
    }, new Map);

console.log(filtered);

Я думаю, что Лодаш uniq() очень полезно

let data = [1,2,3,1,2,3,2,2,3,4,5,5,12,1,23,4,1];
let uniqData = _.uniq(data ,(e) => {
 return e;
});

тогда вывод будет:

[1, 2, 3, 4, 5, 12, 23]

Принятый ответ очень неэффективен. Можно использовать и уменьшить, и хеш-таблицу или объект карты, чтобы повысить производительность. Здесь я предпочел бы карту в месте снижения, хотя. Тем не менее, я предполагаю, что, расширяя подход @Nina Scholz путем удвоения карт, правильный ответ на вопрос OP следующий:

var   a = [1, 2, 3, 1, 2, 3, 2, 2, 3, 4, 5, 5, 12, 1, 23, 4, 1, '23'],
unified = a.map(function(e) {
                  return this.has(e) ? void 0 : (this.set(e,"Cheap Thrills"),e);
                }, new Map());
console.log(unified);

Если бы это был производственный код с массивом произвольной длины, а не с функторами, я бы реализовал метод map со стандартными функциями, поскольку он вносит дополнительный серьезный прирост производительности в большие массивы. (как в размере 10K+)

Я использовал этот скрипт:

var words = ['one', 'one', 'two', 'three', 'three', 'two'];
    var result = [];
    for(i=0;i<words.length;i++){
      if(result.indexOf(words[i]) == -1){
        result.push(words[i])
      }
    }
Другие вопросы по тегам