Google Apps 脚本 - 函数在 GaS 中不起作用,但在 JS 中起作用

Google Apps Script - Function doesn't work in GaS, but does in JS

我对 Google Apps Script 和 JavaScript 都很陌生,但对两者之间的异同进行了广泛的阅读。然而,尽管如此,我似乎无法理解为什么我一直在处理的 Google 工作表的这个自定义函数将 运行 在 Javascript 中正确,但在 GaS 中却不正确。

我的基本目标是检查名称列表,计算所有重复项,并显示出现次数最多的五个名称,以及它们出现的频率。下面的代码仅占最高结果。

目前脚本如下:

//Initial Declarations
function watchList(data) {
  var first = {};
  var rcount = 0;
  if (data === undefined){data = SpreadsheetApp.getActiveSheet().getRange("B2:B139")}; //Utilized for testing within the script editor

  for (var i = 0; i < data.length; i++){//loop through the names

    rcount = 0;// Reset duplicate count

    for (var r = 0; r < data.length; r++) {//loop through the entire list again for each increment of the array above

      if (data[i] === data[r]) {//Is this name a duplicate?

        rcount++;//If yes, add 1 to the count

      } 
  } 
    if (first.count == undefined || first.count < rcount) {//Does this value have the most duplicates?

      first.name = data[i];//If so, assign the name and count values to the first object
      first.count = rcount;

  } 
  }
return [first.name, first.count];
}

不过,我 return 是: first name on the list, 1

然后,当我将所有代码输入 javascript 编辑器,并将结果记录到控制台时,它完美地工作了!略有改动(考虑到没有附加 sheet)javascript 代码如下:

function watchList() {
  var range = new Array('Name 1', 'Name 1', 
               'Name 1','Name 2',
               'Name 2', 'Name 2', 
               'Name 2', 'Name 3');
  var first = {};
  var rcount = 0;

  for (var i = 0; i < range.length; i++){
    rcount = 0;
    for (var r = 0; r < range.length; r++) {

      if (range[i] == range[r]) {
        rcount++;   
      }   
  } 
    if (first.count === undefined || first.count < rcount) {

      first.name = range[i];
      first.count = rcount;

  } 
  }
 console.log([first.name, first.count]);
 return first.name;
}

watchList();

有人能告诉我我在这里遗漏的任何失误吗?提前致谢!

编辑 - 这已被链接为 "How to Compare JS Arrays" 问题的副本,但至少对我来说,这是一个不同的问题,因为这是关于两个完整的数组,而我的问题正在寻找以不同的速度将各个数组元素相互比较。

问题:

  • getRange() 不是 return 数组。需要 .getValues() 才能从范围中获取数组值。

  • 假设上面是一个简单的错字,getValues() 也不是 return 一个 return 一维数组。它 return 是一个二维数组。自定义函数也 return 二维数组。

  • 说明问题,

function watchList() {
  var range = new Array('Name 1', 'Name 1', 
           'Name 1','Name 2',
           'Name 2', 'Name 2', 
           'Name 2', 'Name 3').map(e=>[e]);// modified to mimick the 2D array returned by `getValues` or in a custom function
  var first = {};
  var rcount = 0;
  
  for (var i = 0; i < range.length; i++){
rcount = 0;
for (var r = 0; r < range.length; r++) {

  if (range[i] == range[r]) {//Two objects are never equal, except when they refer to the same object,i.e., the first time, when both sides refer to the same object in memory. See duplicate question.
    rcount++;   //rcount is 1
  }   
  } 
if (first.count === undefined || first.count < rcount) {//1<1 will never be true; The first name and  first count will stay
  
  first.name = range[i];
  first.count = rcount;
  
  } 
  }
 console.log([first.name, first.count]);
 return first.name;
}

watchList();

解决方案:

  • 在范围
  • 上使用.getValues()
  • 比较基元而不是数组对象。

片段:

function watchList() {
var range = [
  [ 'Name 1' ],
  [ 'Name 1' ],
  [ 'Name 1' ],
  [ 'Name 2' ],
  [ 'Name 2' ],
  [ 'Name 2' ],
  [ 'Name 2' ],
  [ 'Name 3' ]
];// simulate getValues() or custom function arguments B1:B8

  var first = {};
  var rcount = 0;
  
  for (var i = 0; i < range.length; i++){
rcount = 0;
for (var r = 0; r < range.length; r++) {

  if (range[i][0] == range[r][0]) {//compare primitives 
    rcount++;   
  }   
  } 
if (first.count === undefined || first.count < rcount) {
  
  first.name = range[i];
  first.count = rcount;
  
  } 
  }
 console.log([first.name, first.count]);
 return first.name;
}

watchList();

参考文献: