1

我的目标

我正在尝试根据单元格中的值链接同一电子表格中两个不同工作表中的行。基本思想是,如果 Sheet1 中 B 列中的值与 Sheet2 中 B 列中的值匹配,则应将超链接添加到具有 Sheet1 中匹配值的单元格,链接到 Sheet2 中匹配值的整行。

我做了什么

从下面的代码中可以看出,它会查找匹配项,如果找到,它会编辑匹配的值以添加超链接。我不仅想要将“链接”匹配值推送到新数组中,我还想要没有链接的非匹配值。这个想法是,如果找到匹配项,将添加链接,否则仍将添加值,只是没有链接。

function linkToContacts(){
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var Sheet1 = ss.getSheetByName("Sheet1");
    var Sheet2 = ss.getSheetByName("Sheet2");
    var Sheet2ID = Sheet2.getSheetId();

    var arrSheet1 = Sheet1.getRange(4,2,Sheet1.getLastRow()-3).getValues(); // -3 because I have 3 row as headers before the data, which start in row 4 col B
    var arrSheet2 = Sheet2.getRange(4,2,Sheet2.getLastRow()-3).getValues(); // -3 because I have 3 row as headers before the data, which start in row 4 col B

    var arrOutput = [];

    for(var i = 0; i<arrSheet1.length;i++){
      for(var j = 0; j<arrSheet2.length;j++) {
        if(arrSheet1[i][0] === arrSheet2[j][0]){
          arrOutput.push(['=HYPERLINK("#gid=' + Sheet2ID + '&range=' + Sheet2.getRange(j+4,2,1,Sheet2.getLastColumn()-1).getA1Notation() + '";"' + arrSheet1[i][0] + '")']);
        } else {
          arrOutput.push([arrSheet1[i][0]]);
        }
      }
    }

    Sheet1.getRange(4,2,Sheet1.getLastRow()).clearContent();
    Sheet1.getRange(4,2,arrOutput.length).setValues(arrOutput);
  }

问题

这两个数组分别只包含唯一值。问题是,由于双循环,每个项目都通过 arrSheet2 的长度进行检查。例如,让我们想象一下这种情况:

var arrSheet1 = [apple,avocado,banana];
var arrSheet2 = [apple,banana,mango,];

arrOutput导致:

arrOutput = [
          apple(link),apple,apple,
          avocado,avocado,avocado,
          banana(link),banana,banana
];

以一种快速、可能不优雅的方式来解决这个问题,我试图删除重复的 frm arrOutput,但显然带有链接的值和没有的值是不同的,所以使用此解决方案可以获得的最佳效果是:

arrOutput = [
          apple(link),apple,
          avocado,
          banana(link),banana
];

问题

有没有更智能/更有效的方式来

arrOutput = [apple(link),avocado,banana(link)];

或者如果我正在做的事情真的有意义,我应该怎么做才能得到上面的结果?

4

2 回答 2

1

您可以使用Array.prototype.filter创建一个仅包含匹配元素的新数组。如果没有找到任何元素,这将返回一个空数组。

var arrSheet1 = ['apple','avocado','banana'];
var arrSheet2 = ['apple','banana','mango'];

var intersect = arrSheet1.filter(function (element) {
  return arrSheet2.includes(element);
});

// ['apple','banana']

或者没有Array.prototype.includespolyfill:

var intersect = arrSheet1.filter(function (element) {
  return arrSheet2.indexOf(element) !== -1);
})
于 2019-07-26T23:17:56.507 回答
0

问题:

  • 多次双循环和推送数组元素

解决方案:

  • 使用break和条件if语句来控制逻辑

流动:

  • 如果超链接被推送,则中断第二个工作表循环
  • 如果Sheet2中没有超链接,则仅推送Sheet1元素(即,等到Sheet2的最后一个元素被迭代)

片段:

for(var i = 0; i<arrSheet1.length;i++){
  for(var j = 0, k = arrSheet2.length-1; j<=k; j++) {// modified
    if(arrSheet1[i][0] === arrSheet2[j][0]){
      arrOutput.push(['=HYPERLINK("#gid=' + Sheet2ID + '&range=' + Sheet2.getRange(j+4,2,1,Sheet2.getLastColumn()-1).getA1Notation() + '";"' + arrSheet1[i][0] + '")']);
      break; //break j loop to continue next i loop
    } else if(j === k){//push sheet1 only on the last element
      arrOutput.push([arrSheet1[i][0]]);
    }
  }
}

笔记:

  • 使用对象{}可能会更好。将 sheet2 数组转换为 object {val1:hash,val2:hash,...}。然后您可以使用以下方法轻松检查 sheet2 中是否存在 sheet1 元素in
于 2019-07-27T08:21:45.640 回答