【问题标题】:Remove duplicates values in array Google Apps Script删除数组 Google Apps 脚本中的重复值
【发布时间】:2022-01-30 16:08:45
【问题描述】:

我想知道如何从 2 个数组中删除重复值,合并到一个主数组中。

这个值不能从工作表或文档中删除,只能在数组中,这就是为什么我没有使用 clear() 或 clearContents() 内置函数;

我还尝试修改 GAS 教程中的 removeDuplicates() 函数,但它会在从 A 到 Z 的列中抛出行,而不是过滤行...一团糟。

注意事项:

getClients()的参数来自其他函数,可以正常工作。

newClients 列出“用户”工作表中的客户,newUsers 列出另一个名为“数据”的工作表中的用户。

两张表属于同一个电子表格。

newClients 和 newUsers:两个数组都只包含字符串(用户名),并且两者都有重复的值。

因此,目标被确定并删除那些值,原始的和重复的。

我认为应该更容易,但我是 JS 新手,所以我尝试过的一切都没有奏效。

谢谢

守则

function getAllClientsFromData(body,project){

  var ss = SpreadsheetApp.getActiveSpreadsheet();

  // Active the Sheets
  var sheet= ss.getSheets()[1,3];

  // Access data in Sheet "Data"
  var rangeC = ss.getRangeByName("clients"); //A:2:C273  
  var rangeU = ss.getRangeByName("names"); //A5:A

  var clients = rangeC.getValues();
  var users   = rangeU.getValues();

  var lastRow = sheet.getLastRow()-2;

  body += "<h2>Total of " + lastRow + " clients in " + project + "</h2>" 
  body += "<table style=" + STYLE.TABLE + ">";
  body += getClients(ss,clients,users,project);
  body += "</table>";

  return body;  

}

function getClients(ss,clients,users,project){

  var body = "";

  var newClients = [];

  for( var g = 0; g < clients.length; g++ ){

    var currentProject = clients[g][2];

    if( clients[g]!= "" ){

       newClients.push(clients[g][0]);

    } 

  } // end for

  var newUsers = []; 

  for( var u = 0; u < users.length; u++ ){

    if( users[u] != "" ){    

      newUsers.push(users[u][0]);

    }

  } // end for

  var allData = newUsers.concat(newClients);

  var uniqueData = allData.sort();

  body += "<tr><td style=" + STYLE.TD + ">" + uniqueData.join("</td><tr><td style=" + STYLE.TD + ">") + "</td></tr></tr>";

  return body;

}

更新!

答案的过滤效果很好,但我得到的结果与我之前的尝试相同:显示过滤后的结果。我需要将它们从数组中删除。示例:

var array = ['aa','bb','aa','ff','pp', 'pp'];
filtering code...
var array = ['bb','ff'];

我尝试添加 splice() js 方法,但我传递的参数无法正常工作。

【问题讨论】:

  • 当您说“它不起作用”时,实际输出或错误是什么?

标签: google-apps-script


【解决方案1】:

您正在处理的数组不再是二维数组,因为您在排序之前提取了字段...因此您可以使用一个非常简单的重复删除功能,如下所示,并添加了一些 Logger.log 来查看如何它有效。

function test(){
  var array = ['aa','bb','cc','aa','dd','cc']
  Logger.log(removeDups(array));
}

function removeDups(array) {
  var outArray = [];
  array.sort():
  outArray.push(array[0]);
  for(var n in array){
    Logger.log(outArray[outArray.length-1]+'  =  '+array[n]+' ?');
    if(outArray[outArray.length-1]!=array[n]){
      outArray.push(array[n]);
    }
  }
  return outArray;
}

在您的代码中,这将替换行

var uniqueData = allData.sort();

那会变成:

var uniqueData = removeDups(allData);

编辑:

如果字母大小写有问题,您可以修改此代码以忽略它。您应该更改条件排序函数,以便它们都忽略您姓名中的大小写,但最好保留原始字母大小写。

这可以通过下面的代码来实现:

function test(){
  var array = ['aa','bb','Cc','AA','dd','CC'];// an example with Upper and Lower case
  Logger.log(removeDups(array));
}

function removeDups(array) {
  var outArray = [];
  array.sort(lowerCase);
  function lowerCase(a,b){
    return a.toLowerCase()>b.toLowerCase() ? 1 : -1;// sort function that does not "see" letter case
  }
  outArray.push(array[0]);
  for(var n in array){
    Logger.log(outArray[outArray.length-1]+'  =  '+array[n]+' ?');
    if(outArray[outArray.length-1].toLowerCase()!=array[n].toLowerCase()){
      outArray.push(array[n]);
    }
  }
  return outArray;
}

记录器结果:


编辑 2:

这是另一个仅保留唯一值的版本(我没有正确理解您在第一个版本中的要求,因为它保留了一个重复元素...)

我只是添加了一个else if 条件来删除属于一组重复项的元素。(我保留了不区分大小写的版本,但您可以轻松删除它)

function test(){
  var array = ['aa','dd','hh','aa','bb','Cc','cc','cc','bb','nn','bb','AA','dd','CC'];// an example with Upper and Lower case
  Logger.log('original array = '+array);
  Logger.log('unique result = '+removeDups2(array));
}


function removeDups2(array) {
  var uniqueArray = []
  array.sort(lowerCase);
  function lowerCase(a,b){
    return a.toLowerCase()>b.toLowerCase() ? 1 : -1;// sort function that does not "see" letter case
  }
  var temp = array[0];
  for(var n=1 ;n<array.length ; n++){
    Logger.log(temp+'  =  '+array[n]+' ?');
    if(temp.toLowerCase()!=array[n].toLowerCase()){
      uniqueArray.push(array[n]);
      temp = array[n];
    }else if(uniqueArray[uniqueArray.length-1]==temp){
      uniqueArray.pop();// remove it from result if one of the duplicate values
    }
  }
  return uniqueArray;
}

记录器结果新代码:

【讨论】:

  • 仅在最后一个 if 语句中在 outArray[outArray.length-1]array[n] 末尾应用 .toString() 后对我有用。
  • 非常感谢您!我不得不进行更改/添加(我对 JS 几乎一无所知)。我不断收到function () { return this.filter(function (value, index, self) { return self.indexOf(value) === index; }); } ?,所以我将if (outArray[outArray.length - 1] != array[n]) 更改为if (outArray[outArray.length - 1] != array[n] &amp;&amp; n != "unique")。我不知道是什么导致了这个问题,或者我的“修复”是否合适,所以我想由你运行它。再次感谢!
【解决方案2】:

在您的代码中,您没有做任何事情来过滤重复值。 此行只会对数据进行排序,不会为您提供唯一数据。

var uniqueData = allData.sort(); 

“安装”2DArray 库后,您可以在合并的阵列上执行类似操作:https://sites.google.com/site/scriptsexamples/custom-methods/2d-arrays-library

var uniqueData = unique(allData);

另一种选择是创建一个循环并检查重复值,但您应该记住在进行这些匹配之前将字符串的所有值转换为小写。

【讨论】:

    【解决方案3】:

    我创建了这个函数并且它有效。

    function removeDups(data) {
      var newData = [];
    
      data.forEach(function(value) {
          if (newData.indexOf(value) == -1) {
            newData.push(value);
        }
      });
      return newData;
    }
    

    【讨论】:

    • 欢迎来到堆栈溢出。考虑您对代码发表评论以确认它确实工作。请养成在您的代码中记录a)它完成了什么b)如何的习惯,如果不是很明显的话。请重新查看问题最后一段中的示例,了解为什么有人会投票给您的答案无用
    【解决方案4】:

    另一种解决方案:

    function removeDups(array) {
      array.sort()
      var lastValue = !array[0]
      var outArray = array.filter(function(value) {
        if (value == lastValue)
          return false
        lastValue = value
        return true
      })
      return outArray
    }
    

    这也适用于空数组,而一些早期的解决方案在这种特殊情况下会产生 [null]。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-06
      • 2021-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多