Google Apps 脚本变量重新分配
Posted
技术标签:
【中文标题】Google Apps 脚本变量重新分配【英文标题】:Google Apps Script Variable Reassignment 【发布时间】:2015-07-13 07:40:45 【问题描述】:我正在尝试制定一年的员工时间表,一周中的不同日子需要不同数量的员工。我想将名册输出到 Google 电子表格中
我的方法是创建一个包含所有员工姓名的数组,然后在一年中的每一天从员工数组中删除 x 个姓名。 X 等于 staff.length - 今天需要多少人。
我已经编写了代码,但我的输出不是我所期望的。第一天看起来是正确的,但随后的每一天都返回一个空数组。
var staff 在 LoC3 上初始化和分配。但是在 LoC12 上,当我有日志输出 staff 中的内容时,我看到一个空数组。我可以看到将一个空数组分配给 rosterToday 是生成的 rosterFull 是如何为空的,但我不明白将 staff 设置为什么[, , , , , , ]
此外,如果我取消 LoC17 (rosterToday[i] = ""),staff 的幻像重新分配似乎消失了。
有谁知道我在这里做错了什么?
function RosterTest()
var staff = ["Adam", "Bob", "Chris", "Dave", "Ed", "Fred", "Garry"];
var dailyRequirement = [0, 6, 7, 7, 7, 6, 2]; // num staff needed today
var rosterFull = []; // push each day's roster in here
var period = 7; // test with only 7 days, then ramp up to 365
for (var d=0; d<period; d++)
var rosterToday = staff; // initially start with the full roster
var reduce = staff.length - dailyRequirement[d];
Logger.log("d="+d+" staff="+staff);
// when d>=1 staff becomes [, , , , , , ]
for (var i=0; i<reduce; i++)
rosterToday[i] = "";
rosterFull.push(rosterToday);
for (var i=0; i<rosterFull.length; i++)
Logger.log(rosterFull[i]); // shows an arr of len 7 with empty arrs
// spreadsheet.getRange(row, col, height, width).setValues(rosterWeek);
我知道这将始终优先考虑人员数组中的前几个人员,但我已经有代码可以对它们进行洗牌。这只是一些孤立的行。
【问题讨论】:
Array.slice() 是你的朋友。 我可以,但我希望这些元素在内部/今天数组中保留为空白,因此当我调用 setValues() 时,实际的工作人员仍然在列中对齐。 您接近员工名册的方式总是从员工列表的“左侧”中挑选 - 这是您想要的吗?亚当总是被选中,而加里只有 3 次? 【参考方案1】:没有深入了解您所问的是否是您真正想做的事情,原因是staff
在第一次运行后为空,因为该行
rosterToday = staff;
这会将人员分配为对 rosterToday 的引用 - 所以所有 rosterToday[i]
所做的也适用于 staff
。您需要制作 rosterToday 副本。
rosterToday = staff.slice(); //makes a shallow copy of the array
这将解决该特定问题。
除此之外,您还可以使用 Array.slice()
复制您在那里的内容
var rosterToday = [];
var rosterLength = staff.length;
for (var d = 0; d < dailyRequirement.length; d += 1)
rosterDay = staff
.slice(0,dailyRequirement[d]-1)
.concat(Array(rosterLength - d));
rosterFull.push(rosterDay)
但我不相信这是你想要做的。
【讨论】:
谢谢乔纳森。我不知道 JS 切换到通过引用传递对象/arr 分配,而不是通过值传递原语。是的,我也知道 Adam 比 Garry 做的工作要多得多,但我有更进一步的代码,记录每天分配的最后一个人,然后首先分配明天名单上的下一个人。【参考方案2】:我不确定为什么人员数组看起来是空的,但我认为这可能是尝试将二维数据集分配给一维数组的效果。您希望变量 rosterFull 包含每天所需的名称。这意味着您需要一个具有 7 X the-amount-of-needed-staff-per-day 维度的数组。
function RosterTest()
var staff = ["Adam", "Bob", "Chris", "Dave", "Ed", "Fred", "Garry"];
var dailyRequirement = [0, 6, 7, 7, 7, 6, 2]; // num staff needed today
var period = 7; // test with only 7 days, then ramp up to 365
var rosterFull = new Array(7); // create an array with 7 rows that represent the 7 days of the week
for (var d=0; d<period; d++)
var rosterToday = [];
for(var i=0; i<dailyRequirement[d]; i++)
rosterToday[i] = staff[i];
rosterFull[d] = rosterToday; //assign the array with the required staff to the corresponding day.
我不理解变量 reduce。这会给你今天不需要的人数,而我想你想要的人数是需要的人数。
【讨论】:
我正在反过来看这个。将每个人分配到 rosterToday,然后为今天不需要的人分配空白,这是为了保留所有这些“内部”数组的长度,这些数组被推入 rosterFull。通过保留相同的长度,我可以调用 setValues(rosterFull) 并将结果保存在 Google 电子表格中以上是关于Google Apps 脚本变量重新分配的主要内容,如果未能解决你的问题,请参考以下文章
Google Apps 脚本按钮:我可以分配一个未附加到工作表的“全局”脚本吗?
如何使用google apps脚本在自定义函数中编辑自定义函数的调用单元格?