Удалить только один из дублированных элементов в ArrayList - PullRequest
0 голосов
/ 15 февраля 2019

У меня есть несколько массивов, которые каждый раз заполняются разными значениями.Таким образом, массив иногда содержит более одного и того же значения.Так это может выглядеть так: [0, 0, 0, 2, 3, 0].Я хочу иметь возможность удалить один экземпляр целевого значения.Например, если целью было 0, то массив мог бы выглядеть следующим образом: [0, 0, 2, 3, 0].

В данный момент я работаю с этим кодом:
var new_list = grades.filter(e => e !== grade);
Примечание:grades - это ArrayList, который я получаю из базы данных.Но эта строка собирается удалить все 0. Но я хочу удалить только одну из 0.
РЕДАКТИРОВАТЬ:
Попробовал что-то вроде этого:

let grades = doc.data()[grade_type] || [];
var elementIndex = grades.indexOf(grade);
grades.splice(elementIndex);

Ноне работает.Пример ArrayList [0, 0, 0].Вывод [].

~ filip

Ответы [ 4 ]

0 голосов
/ 17 февраля 2019

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

const grades = [0, 0, 1, 0, 1, 2, 3, 2, 3, 4];

const rmOneDupFrom = (arr, n) =>
{
    let nCounter = 0;

    for (let i = 0; i < arr.length; i++)
    {
        nCounter = arr[i] === n ? nCounter + 1 : nCounter;

        if (nCounter > 1)
        {
            arr.splice(i, 1);
            return;
        }
    }
}

console.log("Original => ", JSON.stringify(grades));

// Remove one duplicate of element 3.
rmOneDupFrom(grades, 3);
console.log("one 3 removed => ", JSON.stringify(grades));

// Remove one duplicate of element 0.
rmOneDupFrom(grades, 0);
console.log("one 0 removed => ", JSON.stringify(grades));

// Try to remove one duplicate of element 4.
rmOneDupFrom(grades, 4);
console.log("none removed (4 hasn't duplicates) => ", JSON.stringify(grades));

Следует отметить, что этот подход изменяет исходный массив, если вы этого не хотите, вы можете сделать копию исходного массива, прежде чем передать его в rmOneDupFrom() с slice () , пример:

let grades = [0, 0, 1, 0, 1, 2, 3, 2, 3, 4];

const rmOneDupFrom = (arr, n) =>
{
    let nCounter = 0;

    for (let i = 0; i < arr.length; i++)
    {
        nCounter = arr[i] === n ? nCounter + 1 : nCounter;

        if (nCounter > 1)
        {
            arr.splice(i, 1);
            return;
        }
    }
}

let gradesCopy = grades.slice(0);
rmOneDupFrom(gradesCopy, 3);
console.log("Original => ", JSON.stringify(grades));
console.log("Copy => ", JSON.stringify(gradesCopy));
0 голосов
/ 15 февраля 2019

Вы можете удалить второе появление того же значения и установить флажок для сохранения всех остальных значений.

var array = [0, 0, 0, 2, 3, 0, 3, 3],
    f = {};

array = array.filter(v => f.all || (f.all = !(f[v] = (f[v] || 0) + 1 !== 2)));

console.log(array);
0 голосов
/ 15 февраля 2019

ОБНОВЛЕНИЕ: следующее удалит второй экземпляр дубликата (самый ранний, который мы можем обнаружить, что дубликат, фактически, существует):

function removeOneTargetDuplicate(list, target) {
  let result = [];
  let count = 0;

  for (let i = 0; i < list.length; i++) {
    if (list[i] === target) {
      count++;
      if (count === 2) {
        continue;
      }
    }
    result.push(list[i]);
  }
  return result;
}

Следующее решение удалит первый экземплярдубликат, хотя и с немного большей сложностью, но все же с линейной временной сложностью:

function removeOneTargetDuplicate(list, target) {
  let result = [];
  let duplicate = false;

  for (let i = 0; i < list.length; i++) {

    // duplicate will only be true if we've removed the first duplicate
    if (list[i] === target && !duplicate) {

      // if we've found the target, check the rest of the array for a duplicate
      for (let j = i + 1; j < list.length; j++) {
        if (list[j] === target) {
          duplicate = true;
        }
      }

      // if that duplicate was found, skip to the next iteration of the for loop and don't add to the result, effectively removing the first instance of the target
      if (duplicate) {
        continue;
      }
    }
    result.push(list[i]);
  }
  return result;
}
0 голосов
/ 15 февраля 2019

После того, как вы обнаружите, у какого элемента есть дубликаты, вы можете использовать splice

grades.splice(elementIndex,1);
...