[英]Google Sheets Random Copy and Sort with Scripts
我想要做的是复制一列并重新排序。 问题是,它捕获所有可用的单元格并使用相同的空间重新排序,从而导致空白。 这个想法是创建锦标赛配对,第一列是花名册本身,后面的列是他们将与之匹配的球员。
我还想添加一行来验证名称不会在同一行中出现两次,重新洗牌直到每一行的列都是唯一的
这是我到目前为止的代码。 我试图通过交换来过滤数据
range2.setValues(shuffleArray(range.getValues()));
为了
range2.setValues(shuffleArray(range.getValues().filter(String)));
但这会导致“范围为 41 时数据行数为 10”错误,显然不是逐字记录。 我试图折叠此屏幕截图中显示的空白区域。
我确信我可以想出如何通过我希望生成的匹配项来扩展它。
function shuffleRange() {
var sheet = SpreadsheetApp.getActive().getSheetByName('SETUP');
var range = sheet.getRange('A31:A')
var range2 = sheet.getRange('C31:C');
range2.clearContents;
range2.setValues(shuffleArray(range.getValues()));
}
function shuffleArray(array) {
var i, j, temp;
for (i = array.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i+1));
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
编辑:::::代码已移至测试表,因此名称和范围不同,我当然在移动样本时调整了样本
function shuffleRange() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet4');
var range = sheet.getRange('A1:A40')
var v = range.getValues().filter(String);
//Match 1
var values = shuffleArray1(v);
while (v.length != [...new Set(values.map(([a]) => a))].length) {
values = shuffleArray1(v);
}
range.offset(0, 1, values.length).setValues(values);
//Match 2
var values2 = shuffleArray2(v);
while (v.length != [...new Set(values2.map(([a]) => a))].length) {
values = shuffleArray2(v);
}
range.offset(0, 2, values.length).setValues(values2);
}
function shuffleArray1(array) {
var i, j, temp;
for (i = array.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i+1));
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
function shuffleArray2(array) {
var u, v, temp;
for (u = array.length - 3; u > 0; u--) {
v = Math.floor(Math.random() * (u+2));
temp = array[u];
array[u] = array[v];
array[v] = temp;
}
return array;
}
range2.clearContents
可能是range2.clearContent()
。sheet.getRange('A31:A')
,检索工作表中的所有行。 当这些点反映在你的脚本中时,如何修改shuffleRange()
如下?
function shuffleRange() {
var sheet = SpreadsheetApp.getActive().getSheetByName('SETUP');
var lastRow = sheet.getLastRow();
var range = sheet.getRange('A31:A' + lastRow);
var range2 = sheet.getRange('C31:C' + lastRow);
range2.clearContent();
var values = shuffleArray(range.getValues()).filter(String);
range.offset(0, 2, values.length).setValues(values);
}
从您的以下新问题中,
本质上,如果该行包含重复项,则必须重新洗牌,直到每一行都包含原始列中的唯一名称,才能为锦标赛创建唯一的比赛配对,这将检查整行,因为有些锦标赛只进行 2 场比赛,有些比赛最多 21 场
在这种情况下,下面的示例脚本怎么样?
function shuffleRange() {
var sheet = SpreadsheetApp.getActive().getSheetByName('SETUP');
var lastRow = sheet.getLastRow();
var range = sheet.getRange('A31:A' + lastRow);
var range2 = sheet.getRange('C31:C' + lastRow);
range2.clearContent();
var v = range.getValues().filter(String);
var values = shuffleArray(v);
while (v.length != [...new Set(values.map(([a]) => a))].length) {
values = shuffleArray(v);
}
range.offset(0, 2, values.length).setValues(values);
}
values
中时,将再次运行shuffleArray
function。从您的以下回复中,
不幸的是,一旦我复制函数以创建第二组结果,它几乎立即产生重复行
我添加了一个新示例,这样您就可以看到我是如何尝试将它扩展到多列结果中的,这将创建一定数量的匹配项。 完成后,我会将计数器换成单元格检查,以便用户可以设置匹配号,但那是以后的事
function shuffleRange() {
var sheet = SpreadsheetApp.getActive().getSheetByName('SETUP');
var range = sheet.getRange('A1:A40');
var v = range.getValues().filter(String);
var createValues = v => {
SpreadsheetApp.flush(); // I'm not sure whether this line is required.
var temp = sheet.getRange(1, 1, 40, sheet.getLastColumn()).getValues();
var existValues = temp[0].map((_, c) => temp.map(r => r[c]).join("")).filter(String);
var values;
do {
values = shuffleArray1(v);
while (v.length != [...new Set(values.map(([a]) => a))].length) {
values = shuffleArray1(v);
}
var check = values.map(([a]) => a).join("");
} while (existValues.some(e => e == check));
return values;
}
var values1 = createValues(v);
range.offset(0, 1, values1.length).setValues(values1);
var values2 = createValues(v);
range.offset(0, 2, values2.length).setValues(values2);
}
添加到 Tanaike 的建议中,我加入了你的两个功能,以便能够重新洗牌。 我不太精通编码,可能有一个更相似的代码版本也可以重新洗牌。 但你可以试试这个:
function shuffleRange() {
var sheet = SpreadsheetApp.getActive().getSheetByName('SETUP');
var lastRow = sheet.getLastRow()
var range = sheet.getRange('A31:A' + lastRow);
var range2 = sheet.getRange('C31:C' + lastRow);
range2.clearContents;
function shuffleArray() {
var i, j, temp;
var array = range.getValues()
var array2 = range.getValues()
var count= 1;
while (count>0){
count=0
for(i=array.length-1;i>0;i--){
j = Math.floor(Math.random() * (i+1));
temp = array2[i];
array2[i] = array2[j];
array2[j] = temp;
}
for(i=0;i<array.length;i++){
if(array[i].toString() == (array2[i]).toString()){count = count+1}
}}
return array2
}
range2.setValues(shuffleArray())
}
我已经尝试了十分之一次,但从来没有重复过:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.