Получить все уникальные значения в массиве JavaScript (удалить дубликаты) - PullRequest
1123 голосов
/ 25 декабря 2009

У меня есть массив чисел, которые я должен убедиться, что они уникальны. Я нашел фрагмент кода ниже в интернете, и он прекрасно работает, пока в массиве нет нуля. Я нашел этот другой скрипт здесь, на SO, который выглядит почти так же, как и он, но он не дает сбоя.

Итак, ради того, чтобы помочь мне учиться, может ли кто-нибудь помочь мне определить, где происходит ошибка прототипа сценария?

Array.prototype.getUnique = function() {
 var o = {}, a = [], i, e;
 for (i = 0; e = this[i]; i++) {o[e] = 1};
 for (e in o) {a.push (e)};
 return a;
}

Больше ответов на повторяющийся вопрос:

Аналогичный вопрос:

Ответы [ 70 ]

1 голос
/ 11 ноября 2016

Я знаю, что на это уже ответили до смерти ... но ... никто не упомянул реализацию linq на javascript. Затем можно использовать метод .distinct() - и он делает код очень простым для чтения.

var Linq = require('linq-es2015');
var distinctValues =  Linq.asEnumerable(testValues)
            .Select(x)
            .distinct()
            .toArray();

var testValues = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 1];

var distinctValues = Enumerable.asEnumerable(testValues)
  .distinct()
  .toArray();

console.log(distinctValues);
<script src="https://npmcdn.com/linq-es5/dist/linq.js"></script>
1 голос
/ 19 сентября 2015

Версия, которая принимает селектор, должна быть довольно быстрой и лаконичной:

function unique(xs, f) {
  var seen = {};
  return xs.filter(function(x) {
    var fx = (f && f(x)) || x;
    return !seen[fx] && (seen[fx] = 1);
  });
}
1 голос
/ 16 сентября 2014

Еще одно решение для кучи.

Недавно мне нужно было сделать отсортированный список уникальным, и я сделал это с помощью фильтра, который отслеживает предыдущий элемент в объекте, подобном этому:

uniqueArray = sortedArray.filter(function(e) { 
    if(e==this.last) 
      return false; 
    this.last=e; return true;  
  },{last:null});
1 голос
/ 04 ноября 2015

Это не чисто, он будет изменять массив, но это самый быстрый. Если ваш быстрее, пожалуйста, напишите в комментариях;)

http://jsperf.com/unique-array-webdeb

Array.prototype.uniq = function(){
    for(var i = 0, l = this.length; i < l; ++i){
        var item = this[i];
        var duplicateIdx = this.indexOf(item, i + 1);
        while(duplicateIdx != -1) {
            this.splice(duplicateIdx, 1);
            duplicateIdx = this.indexOf(item, duplicateIdx);
            l--;
        }
    }

    return this;
}

[
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc"
].uniq() //  ["",2,4,"A","abc"]
1 голос
/ 12 декабря 2018

var numbers = [1, 1, 2, 3, 4, 4];

function unique(dupArray) {
  return dupArray.reduce(function(previous, num) {

    if (previous.find(function(item) {
        return item == num;
      })) {
      return previous;
    } else {
      previous.push(num);
      return previous;
    }
  }, [])
}

var check = unique(numbers);
console.log(check);
1 голос
/ 23 августа 2018

У меня есть решение, которое использует es6 метод сокращения и поиска вспомогательных методов для удаления дубликатов.

let numbers = [2, 2, 3, 3, 5, 6, 6];

const removeDups = array => {
  return array.reduce((acc, inc) => {
    if (!acc.find(i => i === inc)) {
      acc.push(inc);
    }
    return acc;
  }, []);
}

console.log(removeDups(numbers)); /// [2,3,5,6]
1 голос
/ 19 декабря 2017

Аналогично решению @sergeyz, но более компактно благодаря использованию более кратких форматов, таких как функции стрелок и array.includes. Предупреждение: JSlint будет жаловаться из-за использования логической или и запятой. (хотя все еще совершенно допустимый JavaScript)

my_array.reduce((a,k)=>(a.includes(k)||a.push(k),a),[])
1 голос
/ 24 февраля 2017

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

Следующий фильтр фильтрует массив значений, проверяя, чтобы первый и последний индексы данного значения были равны. Если индекс равен, это означает, что значение должно появиться только один раз.

var values = [1, 2, 3, 4, 5, 2, 4, 6, 2, 1, 5];

var unique = values.filter(function(value) {
  return values.indexOf(value) === values.lastIndexOf(value);
});

console.log(unique); // [3, 6]

Основываясь на отзывах, которые я неправильно понял, вот альтернативный подход, который возвращает уникальные, не повторяющиеся значения из массива значений.

var values = [1, 2, 3, 4, 5, 2, 4, 6, 2, 1, 5];
var unique = values.reduce(function(unique, value) {
  return unique.indexOf(value) === -1 ? unique.concat([value]) : unique;
}, []);

console.log(unique); // [1, 2, 3, 4, 5, 6]
1 голос
/ 27 октября 2017

Это функция ES6, которая удаляет дубликаты из массива объектов, фильтруя по указанному свойству объекта

function dedupe(arr = [], fnCheck = _ => _) {
  const set = new Set();
  let len = arr.length;

  for (let i = 0; i < len; i++) {
    const primitive = fnCheck(arr[i]);
    if (set.has(primitive)) {
      // duplicate, cut it
      arr.splice(i, 1);
      i--;
      len--;
    } else {
      // new item, add it
      set.add(primitive);
    }
  }

  return arr;
}

const test = [
    {video:{slug: "a"}},
    {video:{slug: "a"}},
    {video:{slug: "b"}},
    {video:{slug: "c"}},
    {video:{slug: "c"}}
]
console.log(dedupe(test, x => x.video.slug));

// [{video:{slug: "a"}}, {video:{slug: "b"}}, {video:{slug: "c"}}]
1 голос
/ 26 июня 2018

Вы можете использовать Ramda.js , функциональную библиотеку JavaScript для этого:

var unique = R.uniq([1, 2, 1, 3, 1, 4])
console.log(unique)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
...