【问题标题】:Delete only one of the duplicated elements in ArrayList仅删除 ArrayList 中的重复元素之一
【发布时间】:2019-07-10 00:17:14
【问题描述】:

我有几个数组,每次都用不同的值填充。所以数组有时包含多个相同的值。所以它可能看起来像这样:[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] 。输出[]

~菲利普

【问题讨论】:

  • 您要删除哪个零?还是要删除第一个找到的重复项?
  • @NinaScholz 应该删除哪个 0 并不重要:)
  • 请注意此代码:var new_list = grades.filter(e => e !== grade); 将过滤所有与grade 不同的元素,但如果您的数组中有N equal 值与等级不同,他们都将被退回。因此,不会删除任何重复的内容。
  • 仅供参考,ArrayList 是 Java 术语,表示其特定的数组实现。 Javascript 只有“数组”。
  • 如果你有这个数组,另一件事将有助于澄清你的问题:[0,0,1,1,1,2,2,2] 你想作为输出得到[0,1,1,1,2,2,2][0,1,1,2,2]?

标签: javascript arraylist filter duplicates google-cloud-firestore


【解决方案1】:

在检测到哪个元素有重复项后,您可以使用splice

grades.splice(elementIndex,1);

【讨论】:

  • 但是如何找出elementIndex呢?
  • grades.indexOf(0) 会给你索引。您可能需要使用循环来计算数组的所有元素,然后找到索引并拼接每个重复多次的元素。
  • 您必须明确写出您只想删除一项:grades.splice(elementIndex,1);。添加第二个参数,你的代码就可以正常工作了。
  • 感谢您的帮助#
【解决方案2】:

您可以删除相同值的第二次出现并使用一个标志来保留所有其他值。

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);

【讨论】:

    【解决方案3】:

    检查下一个方法,这里我们循环遍历数组,直到找到要删除的元素的第一个副本,当我们找到它时,我们使用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));

    您应该注意,这种方法会改变原始数组,如果您不希望这样,您可以在将原始数组通过slice() 传递给rmOneDupFrom() 之前制作一个副本,例如:

    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));

    【讨论】:

      【解决方案4】:

      更新: 以下将删除重复的第二个实例(我们最早可以检测到实际上存在重复):

      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;
      }
      

      【讨论】:

      • 不错的解决方案。很抱歉造成误解,但我想删除一个特殊的数字(var 等级),如果该等级在 ArrayList 中不止一次,请删除它们。
      • 谢谢,我更新了上面的解决方案以解决该用例
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 2014-09-19
      • 2012-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多