Удаление обоих значений из массива, если они повторяются - JavaScript/jQuery
У меня есть массив здесь:
var myArr = [1, 1, 2, 5, 5, 7, 8, 9, 9];
Теперь я хочу удалить оба экземпляра дубликата. Таким образом, желаемый результат не:
var myArr = [1, 2, 5, 7, 8 ,9];
но
var myArr = [2, 7, 8];
В основном я знаю, как удалить дубликаты, но не в том, что это особый способ. Вот почему любая помощь будет действительно оценена!
Обратите внимание: мой массив заполняется строками. Числа здесь использовались только в качестве примера.
Ответы
Ответ 1
jsfiddle для этого кода:
var myArr = [1, 1, 2, 5, 5, 7, 8, 9, 9];
var newArr = myArr;
var h,i,j;
for(h = 0; h < myArr.length; h++) {
var curItem = myArr[h];
var foundCount = 0;
// search array for item
for(i = 0; i < myArr.length; i++) {
if (myArr[i] == myArr[h])
foundCount++;
}
if(foundCount > 1) {
// remove repeated item from new array
for(j = 0; j < newArr.length; j++) {
if(newArr[j] == curItem) {
newArr.splice(j, 1);
j--;
}
}
}
}
Ответ 2
Где бы ни возникало удаление дубликатов, неплохо было бы использовать установить структуру данных.
JavaScript не имеет встроенной реализации, но ключи объекта работают так же хорошо - и в этом случае помогают, потому что тогда значения могут использоваться для отслеживания того, как часто элемент появляется в массиве:
function removeDuplicates(arr) {
var counts = arr.reduce(function(counts, item) {
counts[item] = (counts[item]||0)+1;
return counts;
}, {});
return Object.keys(counts).reduce(function(arr, item) {
if(counts[item] === 1) {
arr.push(item);
}
return arr;
}, []);
}
var myArr = [1, 1, 2, 5, 5, 7, 8, 9, 9];
removeDuplicates(myArr);
Посмотрите пример на jsfiddle.
В качестве альтернативы вы не можете использовать вызовы reduce()
, а вместо этого используйте for
и for(item in counts)
loop:
function removeDuplicates(arr) {
var counts = {};
for(var i=0; i<arr.length; i++) {
var item = arr[i];
counts[item] = (counts[item]||0)+1;
}
var arr = [];
for(item in counts) {
if(counts[item] === 1) {
arr.push(item);
}
}
return arr;
}
Посмотрите пример на jsfiddle.
Ответ 3
СОЕДИНЕН с лучшим ответом:
var myArr = [1, 1, 2, 5, 5, 7, 8, 9, 9];
function removeDuplicates(arr) {
var i, tmp;
for(i=0; i<arr.length; i++) {
tmp = arr.lastIndexOf(arr[i]);
if(tmp === i) {
//Only one of this number
} else {
//More than one
arr.splice(tmp, 1);
arr.splice(i, 1);
}
}
}
Ответ 4
Здесь моя версия
var a = [1, 1, 2, 5, 5, 7, 8, 9, 9];
function removeIfduplicate( arr ) {
var discarded = [];
var good = [];
var test;
while( test = arr.pop() ) {
if( arr.indexOf( test ) > -1 ) {
discarded.push( test );
continue;
} else if( discarded.indexOf( test ) == -1 ) {
good.push( test );
}
}
return good.reverse();
}
x = removeIfduplicate( a );
console.log( x ); //[2, 7, 8]
Ответ 5
Если это просто буквенно-цифровое, дубликаты чувствительны к регистру, и их может быть не более двух из любого элемента, тогда что-то вроде этого может работать:
var a = [2, 1, "a", 3, 2, "A", "b", 5, 6, 6, "B", "a"],
clean_array = $.map(a.sort(), function (v,i) {
a[i] === a[i+1] && (a[i] = a[i+1] = null);
return a[i];
});
// clean_array = [1,3,5,"A","B","b"]
Ответ 6
В этом примере мы берем два массива в качестве аргументов функции, из которых мы собираемся печатать только уникальные значения обоих массивов, следовательно, удаляя значения, которые присутствуют в обоих массивах.
Сначала я соединяю оба массива в один. Затем я беру каждое значение массива за раз и зацикливаюсь над самим массивом, ища его отсутствие. если нет вхождения (т.е. count), равного 1, то мы нажимаем этот элемент в массив результатов. Затем мы можем вернуть массив результатов.
function diffArray(arr1, arr2) {
var newArr = [];
var myArr=arr1.concat(arr2);
var count=0;
for(i=0;i<myArr.length;i++){
for(j=0;j<myArr.length;j++){
if(myArr[j]==myArr[i]){
count++;
}
}
if(count==1){
newArr.push(myArr[i]);
}
count=0;
}
return newArr;
}
Ответ 7
Вы можете использовать Set (доступно в IE 11+), как показано ниже
const sourceArray = [1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8];
const duplicatesRemoved = new Set();
sourceArray.forEach(element => {
if (duplicatesRemoved.has(element)) {
duplicatesRemoved.delete(element)
} else {
duplicatesRemoved.add(element)
}
})
console.log(Array.from(duplicatesRemoved))
NB Функции стрелок не поддерживаются в старых браузерах. Вместо этого используйте нормальный синтаксис функции. Тем не менее, Array.from
может быть легко заполнен для старых браузеров.
Попробуй это здесь.
Ответ 8
EDIT: Вот jspref http://jsperf.com/deleting-both-values-from-array
http://jsfiddle.net/3u7FK/1/
Это самый быстрый способ сделать это за два прохода без использования причудливых трюков и сохранения его гибкости. Вы сначала прокручиваетесь и находите счетчик каждого события и помещаете его в парную пару. Затем снова прокрутите его и отфильтруйте те, где счетчик больше 1. Это также имеет преимущество в применении других фильтров, чем просто "больше 1"; а также наличие количества встречных событий, если вам нужно это для чего-то еще.
Это должно работать и с строками, а не с цифрами.
http://jsfiddle.net/mvBY4/1/
var myArr = [1, 1, 2, 5, 5, 7, 8, 9, 9];
var map = new Object();
for(var i = 0; i < myArr.length; i++)
{
if(map[myArr[i]] === undefined)
{
map[myArr[i]] = 1;
}
else
{
map[myArr[i]]++;
}
}
var result = new Array();
for(var i = 0; i < myArr.length; i++)
{
if(map[myArr[i]] > 1)
{
//do nothing
}
else
{
result.push(myArr[i]);
}
}
alert(result);