【问题标题】:Google Apps Script: Comparing Arrays for Unique ValuesGoogle Apps 脚本:比较数组的唯一值
【发布时间】:2018-08-01 02:50:14
【问题描述】:

我正在使用HERE 提供的解决方案来比较两个数组。提供的示例将在两个数组中找到的值返回到 Array1 (same),并将值仅在一个或另外两个 Array2 (diff) 上找到。

问题:当我将它应用到我自己的脚本时,valuesDATA 什么也不返回,valuesCheckSeeding 返回两个数组中的所有值

期望结果:我有两个数组,我想从中创建第三个数组,或者只从第一个数组valuesDATA 中选择第二个数组中不存在的值, valuesCheckSeeding。使用上面的解决方案,我试图将valuesCheckSeedingvaluesDATA 中未找到的所有值推送到valuesDATA

valuesDATA 的示例: "U09 F Harford FC Hill/Healey - A 医学博士 CMSA 女子星期六 U09 A/B 北 总理 - 顶部 TID0118"

我做错了什么?我在循环中修改了matchfound==falsematchfound=true,但这仍然没有给我想要的结果。

最相关的片段

var matchfound = false;

for (var i = 0; i < valuesDATA.length; i++) {
  matchfound=false;
    for (var j = 0; j < valuesCheckSeeding.length; j++) {
      if (valuesDATA[i] == valuesCheckSeeding[j]) {
        valuesCheckSeeding.splice(j, 1);
        matchfound=true;
        continue;
        }
        }
          if (matchfound==false) {
            valuesCheckSeeding.push(valuesDATA[i]);
            valuesDATA.splice(i, 1);
            i=i-1;
            }
          }

根据以下评论/答案编辑的工作脚本

//UPDATE SEEDING SHEET
function updateSeedingSheet() {

var today = Utilities.formatDate(new Date(),Session.getScriptTimeZone(), "MM/dd/yyyy hh:mm a");   

//INPUT SHEET INFO
var inputCurrentRow = 4;
var inputCurrentColumn = 20;
var inputNumRows = 1000;
var inputNumColumns =1;

var ssInput = SpreadsheetApp.openById('1Wzg2BklQb6sOZzeC0OEvQ7s7gIQ07sXygEtC0CSGOh4');
var sheetDATA = ssInput.getSheetByName('DATAREF');
var rangeDATA = sheetDATA.getRange(inputCurrentRow, inputCurrentColumn, inputNumRows, inputNumColumns);
var valuesDATA = rangeDATA.getValues();


//SEEDING SHEET INFO
var seedingCurrentRow = 4;
var seedingCurrentColumn = 1;
var seedingNumRows = 1000;
var seedingNumColumns = 1;

var ssSeeding = SpreadsheetApp.openById('1DuCHeZ3zba-nHq-7vYTrylncPGqcA1J9jNyW9DaS3mU');
var sheetSeeding = ssSeeding.getSheetByName('Seeding');
var rangeCheckSeeding = sheetSeeding.getRange(4, 102, 1000, 1);
var columnToClear = sheetSeeding.getRange(seedingCurrentRow, seedingCurrentColumn, seedingNumRows, seedingNumColumns);
var valuesCheckSeeding = rangeCheckSeeding.getValues();


//METHOD TO FILTER
valuesCheckSeeding = valuesCheckSeeding.map(function(e){return e[0];}); //flatten this array
var filteredArr = valuesDATA.filter(function(e){
    return !(this.indexOf(e[0])+1);
},valuesCheckSeeding);
Logger.log(filteredArr);
Logger.log(filteredArr.length);

var rangeSeeding = sheetSeeding.getRange(seedingCurrentRow, seedingCurrentColumn, filteredArr.length, seedingNumColumns);

sheetSeeding.getRange('A1').setValue(today);
columnToClear.clearContent();
rangeSeeding.setValues(filteredArr);



/*
//ALTERNATIVE METHOD USING LOOPS
for (var i = 0; i < valuesDATA.length; i++) {
    for (var j = 0; j < valuesCheckSeeding.length; j++) {
      if (valuesDATA[i][0] == valuesCheckSeeding[j][0]) {
        valuesDATA.splice(i, 1);
        i--; //account for the splice
        break; //go to next i iteration of loop
          }
       }
     }
          Logger.log("VALUES DATA:" + valuesDATA);
          Logger.log("VALUES CHECK SEEDING: " + valuesCheckSeeding);         

//sheetSeeding.getRange('A1').setValue(today);
//rangeSeeding.clearContent();
//rangeSeeding.setValues(valuesDATA); //INCORRECT RANGE HEIGHT, WAS 71 BUT SHOULD BE 1000 - Is splice affecting this? 

*/

}//END FUNCTION

【问题讨论】:

  • 在迭代数组时不要splice 一个数组,否则逻辑将很难理解...如果要将一个数组分成两个,最好将push 分成两个全新的数组
  • 请展示valuesDATA 的内容示例(都是原始值,对吗?没有对象?)如果内容不是简单的原始值,知道{key: 1} !== {key: 1} 可能会有所启发跨度>
  • “U09 F Harford FC Hill/Healey - A MD CMSA Girls Saturday U09 A/B North Premier - Top TID0118”是直接从电子表格中提取的 valuesDATA 内容示例。我有两个数组,我想从中创建第三个数组,或者只从第一个数组valuesDATA 中选择第二个数组valuesCheckSeeding 中不存在的值。我将更新我的问题以反映这两点。
  • 帮自己一个忙,查看与语言无关的算法来比较集合。然后查看将一个集合与一个可迭代对象进行比较。然后查看从可迭代对象构造集合。
  • (由于 Apps Script 还没有 Set 类,因此您必须使用老式方法。)

标签: javascript google-apps-script


【解决方案1】:

V8(ES2016更新):

  • 您可以使用更新更高效的set

const array1 = [[1],[2],[3]],
array2 = [[1],[3],[4]],
set = new Set(array2.flat())
console.info(array1.filter(e => !set.has(e[0])))
//expected output [[2]]

  • 您正在检查一个二维数组。您需要使用 [i][0][j][0]
  • 你可以试试只拼接valuesDATA

试试

for (var i = 0; i < valuesDATA.length; i++) {
    for (var j = 0; j < valuesCheckSeeding.length; j++) {
      if (valuesDATA[i][0] == valuesCheckSeeding[j][0]) {
        valuesDATA.splice(i, 1);
        i--; //account for the splice
        break; //go to next i iteration of loop
        }
     }
}
Logger.log(valuesDATA);

或者,试试

valuesCheckSeeding = valuesCheckSeeding.map(function(e){return e[0];}); //flatten this array
var filteredArr = valuesDATA.filter(function(e){
    return !(this.indexOf(e[0])+1);
},valuesCheckSeeding);
Logger.log(filteredArr);

【讨论】:

  • 那行得通。当我自己用两个循环完成时,它非常慢。我遇到了上面描述的方法,它更快,所以我试图从中构建,我错过了一些小东西,比如[i][0].map 对我来说是新的,还有一些需要研究的东西。谢谢!
  • 我知道这是旧的,但只是想指出,filteredArr 在 Logger.log 中拼写错误。
  • 我也注意到了 V8 版本。超级快。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多