Как я могу найти значение в массиве и удалить только одно из этих значений, если найдено 2 или более? - PullRequest
2 голосов
/ 07 июня 2011

У меня есть массив

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

Я хочу знать, могу ли я удалить только 1 элемент, если он найдет 2 или более одинаковых значения в массиве.Так, например, если он найдет

"a", "a"

, он удалит один из этих "a"

Это мой текущий код:

var intDennis = 1;
                        for (var i = 0; i < aos.length; i++) {
                            while (aos[i] == aos[intDennis]) {
                                aos.splice(i, 1);
                                intDennis++;
                                console.log(aos[intDennis], aos[i]);
                            } 
                            intDennis = 1;
                        }

ПРИМЕЧАНИЕ: мой массив отсортирован.

Ответы [ 6 ]

2 голосов
/ 07 июня 2011

Отредактировано после лучшего понимания варианта использования OP. Обновленный тест решения и скрипки для включения предложения от pst в комментарии.

(Не даром, но этот метод не требует сортировки исходного массива.)

Попробуйте это ...

var elements = [];
var temp = {};
for (i=0; i<aos.length; i++) {
    temp[aos[i]] = (temp[aos[i]] || 0) + 1;
}
for (var x in temp) {
    elements.push(x);
    for (i=0; i<temp[x]-2; i++) {
        elements.push(x);
    }
}

Проверка скрипки

1 голос
/ 07 июня 2011

Поскольку вы сказали, что у вас есть отсортированный массив, вам нужно только удалить второй раз, когда элемент найден. Вам нужен только один для . Функция splice() возвращает удаленный элемент, поэтому просто используйте его, чтобы не удалять больше элементов такого типа.

Это решение более чистое и эффективное .

var aos = ["a","a","a","b","b","c","d","d"];
var lastRemoved = "";
for (var i = 1; i < aos.length; i++) {
    if (aos[(i-1)] == aos[i] && lastRemoved != aos[i]) {
         lastRemoved = aos.splice(i, 1);
    }
}

Код проверен и работает . Результат: ["a", "a", "b", "c", "d"]

0 голосов
/ 07 июня 2011

Я бы не мутировал ввод, то есть не использовал splice.Это значительно упростит проблему.Использование нового объекта массива здесь может быть более эффективным .Этот подход использует тот факт, что входной массив отсортирован.

Рассмотрим: ( jsfiddle demo )

var input = ["a","a","a","b","b","c","d","d"]
var result = []

for (var i = 0; i < input.length; i++) {
    var elm = input[i]
    if (input[i+1] === elm) {
        // skip first element (we know next is dup.)
        var j = i + 1
        for (; input[j] === elm && j < input.length; j++) {    
            result.push(input[j])
        }
        i = j - 1
    } else {
        result.push(elm)
    }
}

alert(result) // a,a,b,c,d

Счастливое кодирование.


Замените === пользовательским равенством, как вам нужно.Обратите внимание, что это первый элемент, опущенный в выводе, который не всегда может быть «правильным».

0 голосов
/ 07 июня 2011

Я не верю, что есть лучший способ сделать это на несортированном массиве, чем подход с O (n ^ 2) поведением. Учитывая встроенные массивы ES5 (поддерживаются во всех современных браузерах, но не в IE до IE9), работает следующее:

aos.filter(function(value, index, obj) { return obj.indexOf(value) === index; })

0 голосов
/ 07 июня 2011

ОБНОВЛЕННЫЙ ПРИМЕР

function removeDuplicate(arr) {
    var i = 1;
    while(i < arr.length) {
        if(arr[i] == arr[i - 1]) {
            arr.splice(i, 1);
        }
        while(arr[i] == arr[i - 1] && i < arr.length) {
            i += 1;
        }
        i += 1;
    }
    return arr;
}
alert(removeDuplicate(["a","a","a","b","b","c","d","d"]));
0 голосов
/ 07 июня 2011

ОБНОВЛЕНО ОТВЕТИТЬ, ЧТОБЫ УДАЛИТЬ ТОЛЬКО 1 ДУБЛИКАТ:

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

var elements = {};
for (var i = 0; i < aos.length; i++) {
    if(elements[aos[i]]){
        if(elements[aos[i]] == 1){
            aos.splice(i,1);//splice the element out of the array
            i--;//Decrement the counter to account for the reduced array
            elements[aos[i]]++;//Increment the count for the object
        }
    } else {
        elements[aos[i]] = 1;//Initialize the count for this object to 1;
    }
}

Здесь это тестовая скрипка для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...