Получить все уникальные значения в массиве JavaScript (удалить дубликаты)

У меня есть массив чисел, которые я должен убедиться, что они уникальны. Я нашел фрагмент кода ниже в интернете, и он прекрасно работает, пока в массиве нет нуля. Я нашел этот другой скрипт здесь на 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;
}

Больше ответов от дублирующего вопроса:

Подобный вопрос:

140 ответов

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

function uniteUnique(arr, ...rest) {
      const newArr = arr.concat(rest).flat()
      return [...new Set(newArr)]
   }

console.log(uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]))
console.log(uniteUnique([1, 2, 3], [5, 2, 1]))

Надеюсь, это будет кому-то полезно.

Современный расширяемый, быстрый, эффективный и легко читаемый подход с использованием библиотеки iter-ops :

      import {pipe, distinct} from 'iter-ops';

const input = [1, 1, 2, 2, 2, 3]; // our data

const i = pipe(input, distinct()); // distinct iterable

console.log([...i]); //=> [1, 2, 3]

И если ваш ввод представляет собой массив объектов, вы просто предоставите ключевой селектор для distinctоператор.

Если у вас есть массив объектов, и вы хотите uniqueBy функция, скажем, по полю id:

function uniqueBy(field, arr) {
   return arr.reduce((acc, curr) => {
     const exists = acc.find(v => v[field] === curr[field]);
     return exists ? acc : acc.concat(curr);
   }, [])
}

Использование фильтра и склейки

myArray.filter((el,i)=>![...myArray].splice(0,i).includes(el))

Использование Set с прототипом из

Array.from(new Set(myArray))

Использование Set с оператором распространения

[...new Set(myArray)]

(function() {
    "use strict";

    Array.prototype.unique = function unique() {
        var self = this;
        return self.filter(function(a) {
            var that = this;
            // console.log(that);
            return !that[a] ? that[a] = true : false;
        }, {});
    }

    var sampleArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    var distinctArray = sampleArray.unique();
    console.log(distinctArray);
})();
Here is the simple way to solve this problem...

Используйте это без использования какой-либо функции и временной сложности O(n)

function uni(arr){
   var i = 0,uk = 0;
    for (j = 1; j < arr.length; j++){
        if(arr[i] != arr[j]){
            uk++;
            i = j;
        }

    }
    return uk + 1;
}

Code:

function RemoveDuplicates(array) {
    return array.filter(function (value, index, self) {
        return self.indexOf(value) === index;
    });
}

Usages:

var arr = ["a","a","b","c","d", "d"];

console.log(RemoveDuplicates(arr));

Result:

0: "a"
1: "b"
2: "c"
3: "d"

Используя mongoose, у меня был массив ObjectIds для работы.

У меня был массив / список идентификаторов объектов для работы, с которыми сначала нужно было установить строку, а после уникального набора изменить обратно на идентификаторы объектов.

Я бы сортировал массив, тогда все дубликаты - соседи. Затем пройдите по массиву и удалите все дубликаты.

      function getUniques(array) {
  var l = array.length
  if(l > 1) {
    // get a cloned copy and sort it
    array = [...array].sort();
    var i = 1, j = 0;
    while(i < l) {
      if(array[i] != array[j]) {
        array[++j] = array[i];
      }
      i++;
    }
    array.length = j + 1;
  }
  return array;
}

Использование метода Array.prototype.includes() для удаления дубликатов:

(function() {
    const array = [1, 1, 2, 2, 3, 5, 5, 2];
    let uniqueValues = [];
    array.map(num => {
        if (Number.isInteger(num) && !uniqueValues.includes(num)) {
            uniqueValues.push(num)
        }
    });
    console.log(uniqueValues)
}());

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

var ar = [1,3,4,5,5,6,5,6,2,1];
var uarEle = {};
links.forEach(function(a){ uarEle[a] = 1; });
var uar = keys(uarEle)

uar будет иметь уникальные элементы массива.

Я использовал Array# lower для создания уникального Array#.

Array.prototype.unique = function() {
  var object = this.reduce(function(h, v) {
    h[v] = true;
    return h;
  }, {});
  return Object.keys(object);
}

console.log(["a", "b", "c", "b", "c", "a", "b"].unique()); // => ["a", "b", "c"]

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

      const list = [
    {name: "Meier"},
    {name: "Hans"},
    {name: "Meier"},
]
const compare = (a, b) => a.name.localeCompare(b.name);
const uniqueNames = list.makeUnique(compare);
uniqueNames.pushIfAbsent({name: "Hans"}, compare);

Декларация прототипа:

      declare global {
    interface Array<T>  {
        pushIfAbsent(item: T, compare:(a:T, b:T)=>number): number;
    }
    interface Array<T>  {
        makeUnique(compare:(a:T, b:T)=>number): Array<T>;
    }
}
Array.prototype.pushIfAbsent = function <T>(this:T[], item:T, compare:(a:T, b:T)=>number) {
    if (!this.find(existing => compare(existing, item)===0)) {
        return this.push(item)
    } else {
        return this.length;
    }
}
Array.prototype.makeUnique = function <T>(this:T[], compare:(a:T, b:T)=>number) {
    return this.filter((existing, index, self) => self.findIndex(item => compare(existing, item) == 0) == index);
}

Если вы хотите изменить его на месте (не создавая новый массив), вы можете просто:

var
  uniq = function uniq(array) {
    var
      len = array.length;

    while (len--) {
      if (array.indexOf(array[len]) !== len) {
        array.splice(len, 1);
      }
    }

    return array;
  },

  myArray = [1, 2, 2, 4, 2];

console.log(uniq(myArray));
// [1, 2, 4];

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

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

var sortAndDedup = function(array) {
  array.sort(function(a,b){
    if(isNaN(a) && isNaN(b)) { return a > b ? 1 : (a < b ? -1 : 0); }
    if(isNaN(a)) { return 1; }
    if(isNaN(b)) { return -1; }
    return a-b;
  });

  var newArray = [];
  var len = array.length;
  for(var i=0; i<len; i++){
    if(i === 0 || array[i] != array[i-1]){
      newArray.push(array[i]);
    }
  }
};

Не цитируйте меня по этому поводу, но я думаю, что вам нужно использовать строку для имени вашего свойства, например o[e.toString()], а затем преобразовать его обратно, когда вы нажимаете его.

 Array.prototype.unique=function(){ 

   var cr=[];

  this.forEach(function(entry) {
   if(cr.indexOf(entry)<0){
     cr.push(entry);
   }else{
    var index = cr.indexOf(entry);
    if (index > -1) {
     cr.splice(index, 1);
      }
   } 

 });

 return cr;
}

Используйте.toString() для строк.

var givenvalues = [1,2,3,3,4,5,6];
var values = [];
for(var i=0; i<givenvalues.length; i++)
{
    if(values.indexOf(givenvalues[i]) == -1)
    {
        values[values.length] = givenvalues[i];
    }
}

Вы можете использовать вспомогательные функции массивов Reduce() и Some() для достижения вашего результата. Проверьте мой фрагмент кода:

var arrayWithDuplicates = [0, 0, 1, 2, 3, 3, 4, 4, 'a', 'a', '', '', null, null];

var arrayWithUniqueValues = arrayWithDuplicates
                            .reduce((previous, item) => {
                                if(!previous.some(element => element === item)) {
                                    previous.push(item)
                                }
                                return previous;
                            }, []);

console.log('arrayWithUniqueValues', arrayWithUniqueValues)

Я посмотрел код Joeytje50 на jsperf, который сравнил ряд альтернатив. В его коде было много мелких опечаток, которые влияли на производительность и правильность.

Что еще более важно, он тестирует на очень маленьком массиве. Я сделал массив с 1000 целыми числами. Каждое целое число было в 100 раз случайным целым числом от 0 до 1000. Это составляет в среднем около 1000/e = 368 дубликатов. Результаты на jsperf.

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

Array.prototype.getUnique3 = function(){
   var u = Object.create(null), a = [];
   for(var i = 0, l = this.length; i < l; ++i){
      if(this[i] in u) continue;
      a.push(this[i]);
      u[this[i]] = 1;
   }
   return a.length;
}
Другие вопросы по тегам