Найти одинаковые элементы в массиве

Extremosa

Постоялец
Регистрация
11 Май 2015
Сообщения
211
Реакции
171
Помогите найти одинаковые элементы в массиве и оставить их в единственном экземпляре, т.е. сделать из этого массива:
Код:
var array = ['Весна', 'Осень', 'Зима', 'Зима', 'Лето', 'Зима', 'Осень']
вот этот:
Код:
var array = ['Осень', 'Зима']
Желателен вариант на jQuery.
 

qpPeW

Постоялец
Регистрация
4 Окт 2009
Сообщения
139
Реакции
57
Используйте
HTML:
$.unique(array);
 

garphild

Постоялец
Регистрация
19 Май 2009
Сообщения
60
Реакции
31
Помогите найти одинаковые элементы в массиве и оставить их в единственном экземпляре, т.е. сделать из этого массива:
Код:
var array = ['Весна', 'Осень', 'Зима', 'Зима', 'Лето', 'Зима', 'Осень']
вот этот:
Код:
var array = ['Осень', 'Зима']
Желателен вариант на jQuery.
В jQuery в чистом виде нет такой функции. Но делается она просто. Сложность O(n). Если массив предварительно отсортирован, то можно получить чуть более эффективный вариант другим методом с меньшими затратами по памяти.
Код:
/** Исходный массив */
var array = ['Весна', 'Осень', 'Зима', 'Зима', 'Лето', 'Зима', 'Осень']
/** Переменная, использующаяся и как временная и как результат в конце. Лучше использовать ее как временную и потом удалить, а результат вывести в отдельную переменную. */
var doubles = {};
/** Сначала проходим по массиву и создаем объект, ключами которого будут значения исходного массива, а значением количество повторений. */
$.each(array, (i, v) => doubles[v] = doubles[v] ? doubles[v] + 1 : 1);
/** Теперь убираем из массива все элементы, которые не повторяются (количество = 1) */
doubles = Object.keys(doubles).filter((v) => doubles[v] > 1)
/** И получаем нужный результат */
console.log(doubles)

Используйте
HTML:
$.unique(array);

Нужно получить не уникальные элементы, а именно список повторяющихся. Ваш вариант отдает уникальные, т.е чистит массив от повторений.
 

qpPeW

Постоялец
Регистрация
4 Окт 2009
Сообщения
139
Реакции
57
Нужно получить не уникальные элементы, а именно список повторяющихся. Ваш вариант отдает уникальные, т.е чистит массив от повторений.
Мой вариант удаляет из массива все дубликаты, что и просил ТС.
 

garphild

Постоялец
Регистрация
19 Май 2009
Сообщения
60
Реакции
31
Помогите найти одинаковые элементы в массиве и оставить их в единственном экземпляре, т.е. сделать из этого массива:
Код:
var array = ['Весна', 'Осень', 'Зима', 'Зима', 'Лето', 'Зима', 'Осень']
вот этот:
Код:
var array = ['Осень', 'Зима']
Желателен вариант на jQuery.

Мой вариант удаляет из массива все дубликаты, что и просил ТС.

Обратите внимание на "Помогите найти одинаковые элементы в массиве и оставить их в единственном экземпляре". Ваш вариант правильный в случае если нужно удалить дубликаты. Это да. Но задача прямо противоположна. Нужно оставить все дубликаты в единственном экземпляре. А уникальные удалить.
 

qpPeW

Постоялец
Регистрация
4 Окт 2009
Сообщения
139
Реакции
57
Обратите внимание на "Помогите найти одинаковые элементы в массиве и оставить их в единственном экземпляре". Ваш вариант правильный в случае если нужно удалить дубликаты. Это да. Но задача прямо противоположна. Нужно оставить все дубликаты в единственном экземпляре. А уникальные удалить.
Понял, в таком случаи мой вариант действительно не подходит.
 

Absolute

Крокодил ;)
Регистрация
9 Авг 2009
Сообщения
581
Реакции
453
HTML:
var array = ['Весна', 'Осень', 'Зима', 'Весна', 'Зима', 'Лето', 'Весна', 'Зима', 'Осень'];

function getDuplicate(array){
   var arr = [], i = array.length;
   while(i--){
     if(arr.indexOf(array[i]) > -1){
       continue;
     }
     var q = array.length;
     while(q--){
       if(i !== q && array[i] === array[q]){
         arr.push(array[i]);
         break;
      }
    }
  }
  return arr;
}

console.log(getDuplicate(array)); // ["Осень", "Зима", "Весна"]
 

sempais8

Писатель
Регистрация
18 Окт 2015
Сообщения
8
Реакции
8
HTML:
const array = ['Весна', 'Осень', 'Зима', 'Весна', 'Зима', 'Лето', 'Весна', 'Зима', 'Осень'];

function getDuplicate(array) {
    const doubles = [];
    for (let i=0; i<=array.length; i++) {
          array.filter((word, index) => {
                if (word === array[i] && index !== i) doubles.push(word);
          });
    }
    return [...new Set(doubles)];
}

console.log(getDuplicate(array)); // [ "Весна", "Осень", "Зима" ]
 

garphild

Постоялец
Регистрация
19 Май 2009
Сообщения
60
Реакции
31
HTML:
var array = ['Весна', 'Осень', 'Зима', 'Весна', 'Зима', 'Лето', 'Весна', 'Зима', 'Осень'];

function getDuplicate(array){
   var arr = [], i = array.length;
   while(i--){
     if(arr.indexOf(array[i]) > -1){
       continue;
     }
     var q = array.length;
     while(q--){
       if(i !== q && array[i] === array[q]){
         arr.push(array[i]);
         break;
      }
    }
  }
  return arr;
}

console.log(getDuplicate(array)); // ["Осень", "Зима", "Весна"]

HTML:
const array = ['Весна', 'Осень', 'Зима', 'Весна', 'Зима', 'Лето', 'Весна', 'Зима', 'Осень'];

function getDuplicate(array) {
    const doubles = [];
    for (let i=0; i<=array.length; i++) {
          array.filter((word, index) => {
                if (word === array[i] && index !== i) doubles.push(word);
          });
    }
    return [...new Set(doubles)];
}

console.log(getDuplicate(array)); // [ "Весна", "Осень", "Зима" ]

Оба варианта имеют квадратичную сложность. При достаточно большом массиве будет печалька.
 

Absolute

Крокодил ;)
Регистрация
9 Авг 2009
Сообщения
581
Реакции
453
Оба варианта имеют квадратичную сложность. При достаточно большом массиве будет печалька.
Если говорить о больших массивах, то вариант Для просмотра ссылки Войди или Зарегистрируйся оказался самым быстрым по моим тестам.

Тест кода 1.
После нескольких запусков среднее время выполнения: 10
Код:
var array = [];
var limit = 10000;
function getRandom(limit) {
  return Math.floor(Math.random() * Math.floor(limit));
}
for(var i=0; i<limit; i++){
  array.push(String(getRandom(limit)));
}
var time = new Date().getTime();
function getDuplicate(array){
  var doubles = {};
  $.each(array, (i, v) => doubles[v] = doubles[v] ? doubles[v] + 1 : 1);
  doubles = Object.keys(doubles).filter((v) => doubles[v] > 1);
  return doubles;
}
getDuplicate(array);
console.log(new Date().getTime() - time); // 11

Тест кода 2.
После нескольких запусков среднее время выполнения: 1714
Код:
var array = [];
var limit = 10000;
function getRandom(limit) {
  return Math.floor(Math.random() * Math.floor(limit));
}
for(var i=0; i<limit; i++){
  array.push(String(getRandom(limit)));
}
var time = new Date().getTime();
function getDuplicate(array){
   var arr = [], i = array.length;
   while(i--){
     if(arr.indexOf(array[i]) > -1){
       continue;
     }
     var q = array.length;
     while(q--){
       if(i !== q && array[i] === array[q]){
         arr.push(array[i]);
         break;
      }
    }
  }
  return arr;
}
getDuplicate(array);
console.log(new Date().getTime() - time); // 1714

Тест кода 3.
После нескольких запусков среднее время выполнения: 5163
HTML:
var array = [];
var limit = 10000;
function getRandom(limit) {
  return Math.floor(Math.random() * Math.floor(limit));
}
for(var i=0; i<limit; i++){
  array.push(String(getRandom(limit)));
}
var time = new Date().getTime();
function getDuplicate(array) {
    const doubles = [];
    for (let i=0; i<=array.length; i++) {
          array.filter((word, index) => {
                if (word === array[i] && index !== i) doubles.push(word);
          });
    }
    return [...new Set(doubles)];
}
getDuplicate(array);
console.log(new Date().getTime() - time); // 5163

Чистая страница, Chrome 80.0.3987.132 (Последняя на текущий момент)

Несколько быстрее код Для просмотра ссылки Войди или Зарегистрируйся начинает работать если его переписать без jQuery.
Код:
var array = [];
var limit = 10000;
function getRandom(limit) {
  return Math.floor(Math.random() * Math.floor(limit));
}
for(var i=0; i<limit; i++){
  array.push(String(getRandom(limit)));
}
var time = new Date().getTime();
function getDuplicate(array){
  var doubles = {};
  array.forEach((v) => doubles[v] = doubles[v] ? doubles[v] + 1 : 1);
  doubles = Object.keys(doubles).filter((v) => doubles[v] > 1);
  return doubles;
}
getDuplicate(array);
console.log(new Date().getTime() - time); // 6
Такие дела :)
 
Сверху