Получить все уникальные значения в массиве 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 ]

0 голосов
/ 10 марта 2015

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

https://jsfiddle.net/qsdL6y5j/1/

    Array.prototype.getUnique = function () {
        var unique = this.filter(function (elem, pos) {
            return this.indexOf(elem) == pos;
        }.bind(this));
        this.length = 0;
        this.splice(0, 0, unique);
    }

    var duplicates = [0, 0, 1, 1, 2, 3, 1, 1, 0, 4, 4];
    duplicates.getUnique();
    alert(duplicates);

Эта версия вместо этого позволяет вам возвращать новый массив с уникальным значением, сохраняя оригинал (просто передайте true).

https://jsfiddle.net/dj7qxyL7/

    Array.prototype.getUnique = function (createArray) {
        createArray = createArray === true ? true : false;
        var temp = JSON.stringify(this);
        temp = JSON.parse(temp);
        if (createArray) {
            var unique = temp.filter(function (elem, pos) {
                return temp.indexOf(elem) == pos;
            }.bind(this));
            return unique;
        }
        else {
            var unique = this.filter(function (elem, pos) {
                return this.indexOf(elem) == pos;
            }.bind(this));
            this.length = 0;
            this.splice(0, 0, unique);
        }
    }

    var duplicates = [0, 0, 1, 1, 2, 3, 1, 1, 0, 4, 4];
    console.log('++++ ovveride')
    duplicates.getUnique();
    console.log(duplicates);
    console.log('++++ new array')
    var duplicates2 = [0, 0, 1, 1, 2, 3, 1, 1, 0, 4, 4];
    var unique = duplicates2.getUnique(true);
    console.log(unique);
    console.log('++++ original')
    console.log(duplicates2);

Browser support:

Feature Chrome  Firefox (Gecko)     Internet Explorer   Opera   Safari
Basic support   (Yes)   1.5 (1.8)   9                   (Yes)   (Yes)
0 голосов
/ 15 января 2017

Я использовал 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"]
0 голосов
/ 10 мая 2019

У меня есть простой пример, где мы можем удалить объекты из массива с повторяющимся идентификатором в объектах,

  let data = new Array({id: 1},{id: 2},{id: 3},{id: 1},{id: 3});
  let unique = [];
  let tempArr = [];
  console.log('before', data);
  data.forEach((value, index) => {
    if (unique.indexOf(value.id) === -1) {
      unique.push(value.id);
    } else {
      tempArr.push(index);    
    }
  });
  tempArr.reverse();
  tempArr.forEach(ele => {
    data.splice(ele, 1);
  });
  console.log(data);
0 голосов
/ 09 апреля 2019

Это решение должно быть очень быстрым и будет работать во многих случаях.

  1. Преобразование элементов индексированного массива в ключи объекта
  2. Использовать функцию Object.keys

    var indexArray = ["hi","welcome","welcome",1,-9];
    var keyArray = {};
    indexArray.forEach(function(item){ keyArray[item]=null; });
    var uniqueArray = Object.keys(keyArray);
    
0 голосов
/ 15 февраля 2019

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

const uniques = myArray.filter(e => e).filter((e, i, a) => a.indexOf(e) === i);

или

const uniques = [...new Set(myArray.filter(e => e))];
0 голосов
/ 21 января 2018

Вы можете использовать вспомогательные функции массивов redu () и 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)
0 голосов
/ 03 сентября 2017

Создание массива уникальных массивов с использованием поля [2] в качестве идентификатора:

const arr = [
  ['497', 'Q0', 'WTX091-B06-138', '0', '1.000000000', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B09-92', '1', '0.866899288', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B09-92', '2', '0.846036819', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B09-57', '3', '0.835025326', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B43-79', '4', '0.765068215', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B43-56', '5', '0.764211464', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B44-448', '6', '0.761701704', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B44-12', '7', '0.761701704', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B49-128', '8', '0.747434800', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B18-17', '9', '0.746724770', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B19-374', '10', '0.733379549', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B19-344', '11', '0.731421782', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B09-92', '12', '0.726450470', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B19-174', '13', '0.712757036', 'GROUP001']
];


arr.filter((val1, idx1, arr) => !!~val1.indexOf(val1[2]) &&
  !(arr.filter((val2, idx2) => !!~val2.indexOf(val1[2]) &&
    idx2 < idx1).length));

console.log(arr);
0 голосов
/ 06 января 2017

Для массива строк:

function removeDuplicatesFromArray(arr) {
  const unique = {};
  arr.forEach((word) => {
    unique[word] = 1; // it doesn't really matter what goes here
  });
  return Object.keys(unique);
}
0 голосов
/ 24 февраля 2017

Если у вас есть массив объектов, и вы хотите функцию 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);
   }, [])
}
0 голосов
/ 23 февраля 2014

Я посмотрел код 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;
}
...