我正在搜索一组字符串中的一组关键字。然后,如果存在某些单词组合,则将给定的点值分配给记分数组。
在遍历字符串时,我修改了这些数组以跟踪特定字符串的信息。我想将排名从高到低打印出来,然后将数组中的值重置为其原始分配。
因此,我需要一种创建新对象的方法,以便在每次迭代开始时进行修改,以便保留原始数组。
我试图在循环外定义一个变量,然后使用.slice(),Object.create()和[... arr],但是我没有成功。
使函数起作用的唯一方法是在循环的开头使用文字符号定义数组(这没关系,但是如果我需要为数百个注释中的每个注释构建带有数百个关键字的对象,我担心这会拖延处理时间)。
const keyMast = [ //pre-decided keywords, set to false
["No Word", true],
["elbow", false],
["ss" , false],
["student" , false],
["read", false]
];
const combos = [ //for each set of words, assings values for T1, T2,...
["student", true, true, 1, 2, 3, 0, 0, 0, 0, 0],
["elbow", true, true, 3, 2, 1, 0, 0, 0, 0, 0],
["student", "read", true, 0, 0, 0, 1, 2, 3, 0, 0],
["talk", "read", true, 0, 0, 0, 0, 0, 1, 2, 3]
];
const scoreMast= [ //master list of Ts set to zero
["T1", 0],
["T2", 0],
["T3", 0],
["T4", 0],
["T5", 0],
["T6", 0],
["T7", 0],
["T8", 0]
];
//this loop grabs each line in the notes
var i=6; //the first line of notes starts in Cell B6
do {
//reset values for our tables after each note
tempCombo = [...combos];
tempKeywords = [...keyMast];
tempScore = [...scoreMast];
//do stuff with the lists on this line of notes
就像我说的那样,我尝试了很多不同的策略,但是似乎没有任何东西可以产生具有与每次迭代的得分,关键字和组合相同属性的新对象。
两个问题:使用文字符号(var combo = [[blah,blah],[]])在循环内部定义变量是否更容易?这会降低我的代码速度吗?
无论哪种方式,我都想知道如何做到这一点。
编辑 田池要求产出。 Do Loop需要对分数进行排序,然后运行
var suggest = tempScores[0][0] + " " + tempScores[1][0] + " " +tempScores[2][0]
Ss.getRange(i,3). setValue(suggest)
我的客户是委托人。当他们观察老师时,他们会根据8个教学标准(因此,T1,T2 ...)评估他们的工作。他们希望在上课时做笔记,然后让电子表格根据他们使用的关键字来建议最接近该笔记行的标准。
答案 0 :(得分:0)
正如您所发现的,嵌套数组位意味着slice
变量的使用导致仍然访问与slice
所引用的原始变量相同的内部对象。我最简单的提示是“不要修改源数组”。如果您不修改它们,则无需创建新副本。而是编写一个构造相关得分保持对象的函数。
例如:
function getNewScoreObject(numStandards) {
const scorer = [];
for (var i = 0; i < numStandards; ++i) {
scorer.push(["T" + i, 0]);
}
return scorer;
}
这给您每个调用一个不同的对象,因此您可以自由地修改返回值。您不会分享修改combos
或keyMast
对象的方式,因此我们不能真正建议这些功能的实现。
如果您不想为对象编写实例化函数,并且仅因为它们是基元的2D数组,则只需要更深入一层,而内部slice
则Array
:< / p>
teacherReviews.forEach(function (notesOnTeacher) {
var workingCombos = combos.map(function (combo) { return combo.slice(); });
// `workingCombos` is now wholly different than `combos`, but the internal primitives have the same value.
...
});
如果要复制更复杂的对象,则需要对深层克隆进行更详尽的说明。
可能还可以改善应用程序逻辑,以使用对象,但这超出了此处的范围(并且您没有共享逻辑)。作为预告片,我可能已经将combos
定义为具有方便属性名称的对象数组,因此您的代码可以更具表现力:
const combos = [
{
words: [ <words that could be in the note> ],
points: {
T1: <num>,
T2: <num>,
...
T8: <num>
},
requires: "ALL" // "ALL" | "ANY" | "NONE" (logic for earning the points)
},
{
...
];
// case sensitive check
function wordInText(text, word, idx, allWords) {
return text.indexOf(word) !== -1;
}
...
var wordInNoteText = wordInText.bind(null, noteText.toLowerCase()); // prefix all calls with this note's lowercased text.
combos.forEach(function (combo) {
var hasAtLeastOneWord = combo.words.some(wordInNoteText);
var hasAllWords = hasAtleastOneWord && combo.words.every(wordInNoteText);
var earnsPoints = (
(combo.requires === "NONE" && !hasAtLeastOneWord) ||
(combo.requires === "ANY" && hasAtLeastOneWord) ||
(combo.requires === "ALL" && hasAllWords)
);
if (earnsPoints) {
for (var ts in combo.points) {
teacher.score[ts] += combo.points[ts];
}
}
});
...
function writeTeacherData(sheet, teachers) {
const order = ["T1", "T2", "T3", ... "T8"]; // Could `.sort()` a var created from `Object.keys(teacher.score);`
const data = teachers.map(function (teacher) {
var row = [teacher.name, teacher.classPeriod, /** etc */];
Array.prototype.push.apply(row, order.map(function (ts) { return teacher.score[ts]; }));
return row;
});
if (data.length) {
order.unshift("Class Period");
order.unshift("Teacher Name");
// etc
data.unshift(order); // prefix the headers to the data output
sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
}
}
参考文献: