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();
参考文献:
我对 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();