【问题标题】:Compare individual values of 2 multi-dimensional arrays in google script比较谷歌脚本中2个多维数组的单个值
【发布时间】:2016-11-08 13:23:18
【问题描述】:

我有 2 个多维数组,我正在尝试比较数据。虽然嵌套数组的长度可能会因情况而异,但对于每个实例,长度将相同并在两个数组之间镜像,并且每个数组的第一个数组 [0] 将包含完全相同的信息。唯一会/可能会有所不同的是标头可能出现在数组 [0] 中的顺序。可能是

h1、h2、标识

在第一和

ID、h1、h2

在第二个数组中。

完整示例

第一个数组

[ [ Header1 , Header2 , ID ] , [ 数据A , 数据B , 000 ] ]

第二个数组

[ [ Header1 , Header2 , ID ] , [ 数据A , 数据B , 111 ] ]

问题

如何解析、循环、拆分等任何内容(对此仍然很新),以便我可以比较每个值并将它们全部放入一个数组中?

想要的结果

[ [ oldHeader1 , oldHeader2 , oldID , newHeader1 , newHeader2 , newID ] , [ dataA , dataB , 000 , dataA , dataB , 111 ] ]

是的,两个来源的 dataA 和 dataB 应该是相同的。这就是我要比较的东西,每个人的 ID 是唯一应该不同的东西。如果 dataA 不匹配但 dataB 匹配,我想继续但添加日志记录。但这是后面的步骤。

我考虑过遍历第一个数组并获取每个值,然后遍历第二个值以查看该值是否存在。这一切都很好,但我似乎无法弄清楚如何.push 该值并保持一切井井有条。这些值也是从工作表中提取的,但我读到生成数组并使用 Google 的服务器来完成工作比查看每个单元格、vlookup 或查找、返回结果、++ 和迭代更快。

这里的任何建议都会很棒,谢谢!

这是我用来生成 2 个数组的代码,我将作为 FYI 进行比较。也许这里有一些我可以修改的东西?我调用了这个函数两次,一个包含源信息的文件和一个包含目标信息的文件。

//This will take a sheet and an array of headers and return the subset in a new array 
function grabColumnByHeader(headers,sheet,whichID) {
  var initialArray = new Array(); //Array to store sheet data
  var headerIndex = new Array(); //Blank array to house header index(es)
  var outputArray = []; //Will be returned
  var data = sheet.getDataRange(); //all data
  var dataNumRows = data.getNumRows(); //number of rows
  var dataNumCol = data.getNumColumns(); //number of columns
  initialArray = sheet.getRange(1, 1, dataNumRows, dataNumCol).getValues();

  //Get the index(es) of header(s). This is assuming that headers are in row 1
  for (i = 0;i<1;++i){
    for (j = 0;j<dataNumCol;++j){
      //loop through headers var for each header 
      for (k = 0;k<headers.length;++k){
        if(initialArray[i][j].toString().toUpperCase() == headers[k][i].toString().toUpperCase()) {
          headerIndex.push(j);
        }
      }
    }
  }

  //Using the array's indexes from headerIndex, loop through and grab values
  //If coming from SOURCE file, prepend 'SOURCE_'
  for (i = 0;i<dataNumRows;++i) {
    outputArray[i] = [];
    for (j = 0;j<headerIndex.length;++j) {
      if (i == 0 && whichID == 'TRUE') {
        outputArray[i][j] = 'SOURCE_' + initialArray[i][headerIndex[j]];
      } else {
        outputArray[i][j] = initialArray[i][headerIndex[j]];
      }
    }
  }
  //Logger.log(outputArray);
  return outputArray;
}

更新

这是我已经能够一起谷歌 fu 并使用我的基本知识的代码。我意识到它正在执行不必要的循环,这仍在进行中:

  var tempArray = [];
  var idIndex;
  //get index of ID so it can be skipped in comparison
  for (i=0;i<1;++i) {
    for (j=0;j<newData[i].length;++j) {
      if (newData[i][j].toString().toUpperCase() == 'ID') {
        idIndex = j;
      }
    }
  }
  //Logger.log(idIndex);
  for (i=0;i<newData.length;++i) {
    tempArray[i] = [];
    //if on headers, automatically concatenate and add to tempArray
    if (i==0) {
      tempArray[i] = newData[i].concat(oldData[i]);
    }
    else {
      //Logger.log('newData['+i+']');
      for (j=0;j<newData[i].length;++j) {
        //for newData[i][j], begin looking in oldData
        //if we're not comparing indexes then
        if (j != idIndex) {
          //Logger.log('newData['+i+']['+j+']');
          //begin looping through the oldData arrays
          for (k=0;k<oldData.length;++k){               
            //Logger.log('newData['+i+']['+j+'] == oldData['+k+']['+j+']');
            if (newData[i][j] == oldData[k][j]) {
              //NEED TO MAKE SURE HERE THAT ++j IS THE SAME TOO
              tempArray[i] = newData[i].concat(oldData[k]);//continue on with j
              break;

            }
          }
        }
        //continue through for(j)
      }
    }
    //continue through for(i)
  }
  output.getRange(1, 1, tempArray.length, tempArray[0].length).setValues(tempArray);

【问题讨论】:

  • 我不太明白,用你的例子可以用array1.map(function(row, rowI) {return row.concat(array2[rowI]);});达到结果为什么需要比较?两个数组会乱吗?你基本上是想做左连接还是 Vlookup?会有多个匹配项吗?
  • @RobinGertenbach 感谢您的回复。是的,虽然它们出现的“列”的顺序相同,例如h1,h2,idh1,h2,id,但“行”可能是无序的。所以firstArray[1][1] 可能要到secondArray[250][1] 才能找到。一旦找到匹配项,tempArray[i]=firstArray[1].concat(secondArray[250]
  • 那么你想加入 Header1 和 Header2 匹配的两个数组吗?是否可以有多个匹配项,或者两个标头的组合在每个数组中是否唯一?
  • 实际上我想验证第一个数组中的 Header1 应该与第二个数组中的 Header1 匹配。那么 H2 应该与 H2 匹配。如果为 TRUE,则连接这两个数组。否则记录并跳过。在大多数情况下,我期望 h1 == h1 和 h2 == h2,而且我知道 Id 永远不会匹配所以跳过这些。
  • @RobinGertenbach 我已经添加了我能够拼凑起来的代码。

标签: arrays google-apps-script google-sheets


【解决方案1】:

经过反复试验,找到了我自己的答案。可能不是专业人士的做法,但对我有用:

  var tempArray = []; //will be used for output
  var sameArray = []; //will look like this [sameIndex,sameCount]
  var sameIndex = ''; //will get the index number of match to be used when pushing to tempArray
  var sameCount = 0; //if count is == my keys-ID then push to tempArray

  //concat the headers, as this will be a constant
  tempArray[0] = newData[0].concat(oldData[0]);

  for (i=1;i<newData.length;++i) {
    //reset variables after each [i]
    //these are used to verify if my newData array and oldData array are the same
    sameArray = [];
    sameIndex = '';
    sameCount = 0;
    for (j=0;j<newData[i].length;++j) {
      //for newData[i][j], begin looking in oldData
      //we're not comparing our IDs because we know they'll be different
      //pulled those out earlier and set to idIndex
      if (j != idIndex) {
        //begin looping through the oldData arrays
        for (k=1;k<oldData.length;++k){
          for (l=0;l<oldData[k].length;++l) {
            if (l != idIndex) {
              if (newData[i][j] == oldData[k][l]){
                sameArray[0] = k;
                sameArray[1] = ++sameCount;
              }
            }
          }
        }
      }
      //since looped through all of oldData array, check to see
      //if the amount of matches in a single row were keyCount-1
      //keyCount is my variables and we subtract 1 because not comaring IDs
      if (sameArray[1] == keyCount-1) {
        tempArray.push(newData[i].concat(oldData[sameArray[0]]));
      } else {
        //Will be used to catch indexes that didn't match
      }
    }
  }
  output.getRange(1, 1, tempArray.length, tempArray[0].length).setValues(tempArray);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多