我正在使用Google表单收集数据,以供教师确定有资格使用Title 1服务的学生使用。表单将数据提供给Google表格,我想自动按类别对分数求和,然后对每个类别进行排名。我有这段代码可将摘要从一列复制到另一列,但是随后我需要对列进行排名,这就是我遇到的问题。有人可以帮助我了解如何对数据进行排名吗?我认为我可能需要一个for循环-但我被卡住了。谢谢
function CopyRankData()
{
var spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var SourceSheet=spreadSheet.getSheetByName('Ranking')
var srcRange = SourceSheet.getRange('D1:D31');
var destSheet = spreadSheet.getSheetByName('Ranking');
var destRange = destSheet.getRange('I1:I31');
srcRange.copyTo(destRange);
--Need to Rank the column ---[Link to spreadsheet][1]
}
答案 0 :(得分:0)
以下是一个非常简单的实用程序,可以正确模拟RANK
公式(包括升序和降序排名)。如果您需要按范围的另一列对其进行排序或使用another comparator,则很容易更改并使其更通用。
您需要做的是根据某些条件对目标列值的副本进行排序,获取结果索引,然后将其递增1
,因为数组索引基于0
。
/**
* @summary ranks a range by first column
* @param {number[][]} range
* @param {(1|0)} [ascending]
* @return {number[][]}
* @customfunction
*/
const rankRange = (values, ascending = 0) => {
try {
const rows = values.map(v => v).sort((a, b) => {
const aParsed = parseFloat(a[0]);
const bParsed = parseFloat(b[0]);
return ascending ?
aParsed - bParsed :
bParsed - aParsed;
});
return values.map((row) => {
return [rows.findIndex(r => r[0] === row[0]) + 1];
});
} catch (error) {
console.warn(`failed to rank column: ${error}`);
return [[]];
}
};
请确保项目中的V8 runtime is enabled能够正常运行(或在使用前将其转换为ES5语法)。
性能说明-优先使用map(v => v)
来复制浅值。如果您希望项目数量很高,请使用slice()
(由于TheMaster的评论,我决定研究性能下降的原因)。运行下面的交互式代码片段以查看区别:
const rng = document.querySelector("input[type=range]");
const arr = [];
const bench = (func, lbl) => {
console.time(lbl);
func();
console.timeEnd(lbl);
}
rng.addEventListener("change", () => {
const {
value
} = rng;
const toAdd = new Array(+value).fill(42);
arr.length = 0;
arr.push( ...toAdd );
bench(() => arr.slice(), "slice");
bench(() => arr.map(v => v), "map");
});
.rng {
width: 100%
}
<input class="rng" type="range" min="1" max="1e5" step="1">