如何自动随机化46个名称以在Google表格中创建46 x 6个唯一的行和列?

时间:2019-06-10 01:28:49

标签: javascript random google-apps-script google-sheets google-surveys

我正在使用Google表格中的自动化功能。你能帮我吗?

此问题是向46个人发送调查问卷。每个人需要从这46个人中给5个人评分。

Requirements:

1. 1 rater, for 5 uniques ratees
2. No duplicate name per row (it should be 6 unique names in a row)
3. No duplicate name per column (it should be 46 unique names per column)

See image for visualization

预期的输出结果是我们创建46x6的随机名称,在行和列中没有重复项。

-Expected Outcome -Expected outcome

3 个答案:

答案 0 :(得分:2)

流量:

如果可以创建一个上下唯一的矩阵,则可以将其值用作实际名称数组的键。

  • 创建一个2D数字数组,其长度=行数
  • 遍历所需的列数和行数
  • 创建一个临时数组(tempCol)来存储当前列数据
  • 用随机数填充数组
  • 使用indexOf来确定currentrow / current列中是否已经存在任何随机数,如果是,则获取一个新的随机数。
  • 在随机情况下,不可能用上下唯一的随机数填充临时列,请删除临时列并重做此迭代。

摘要:

function getRandUniqMatrix(numCols, numRows) {
  var maxIter = 1000; //Worst case number of iterations, after which the loop and tempCol resets
  var output = Array.apply(null, Array(numRows)).map(function(_, i) {
return [i++]; //[[0],[1],[2],...]
  });
  var currRandNum;
  var getRandom = function() {
currRandNum = Math.floor(Math.random() * numRows);
  }; //get random number within numRows
  while (numCols--) {//loop through columns
getRandom();
for (
  var row = 0, tempCol = [], iter = 0;
  row < numRows;
  ++row, getRandom()
) {//loop through rows
  if (//unique condition check
    !~output[row].indexOf(currRandNum) &&
    !~tempCol.indexOf(currRandNum)
  ) {
    tempCol.push(currRandNum);
  } else {
    --row;
    ++iter;
    if (iter > maxIter) {//reset loop
      iter = 0;
      tempCol = [];
      row = -1;
    }
  }
}
output.forEach(function(e, i) {//push tempCol to output
  e.push(tempCol[i]);
});
  }
  return output;
}
console.info(getRandUniqMatrix(6, 46));

var data1d = data.map(function(e){return e[0]});
var finalArr = getRandUniqMatrix(6, 46).map(function(row){return row.map(function(col){return data1d[col]})}); 
destSheet.getRange(1,1,finalArr.length, finalArr[0].length).setValues(finalArr);

答案 1 :(得分:1)

尝试一下。满足所有这三个要求。

HTML / JS:

<html>
<title>Unique Employees</title>

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
</head>
<table id="survey_table" border="1" width="85%" cellspacing="0">
    <thead>
        <th>Rater</th>
        <th>Ratee1</th>
        <th>Ratee2</th>
        <th>Ratee3</th>
        <th>Ratee4</th>
        <th>Ratee5</th>
    </thead>
    <tbody id="table_body">

    </tbody>
</table>

<script type="text/javascript">
    function arrayRemove(arr, value) {

        return arr.filter(function(ele) {
            return ele != value;
        });

    }

    function getRandomInt(rm_row, rm_col) {
        var temp_arr = [];
        for (var k = 1; k <= 46; k++) {
            temp_arr.push(k);
        }

        for (var k = 0; k < rm_row.length; k++) {
            temp_arr = arrayRemove(temp_arr, rm_row[k]);
        }

        for (var k = 0; k < rm_col.length; k++) {
            temp_arr = arrayRemove(temp_arr, rm_col[k]);
        }

        var rand = temp_arr[Math.floor(Math.random() * temp_arr.length)];

        return rand;

    }

    function exclude_num(row_unq, col_unq) {
        var rand_int = getRandomInt(row_unq, col_unq);

        if (!row_unq.includes(rand_int) && !col_unq.includes(rand_int)) {

            arr_row.push(rand_int);
            return rand_int;
        } else {
            return exclude_num(arr_row, arr_cols);
        }
    }

    for (var i = 1; i <= 46; i++) {
        var arr_row = [];
        arr_row.push(i);

        var table_html = '<tr id="Row' + i + '">';

        for (var j = 1; j <= 6; j++)

        {
            if (j == 1) {
                table_html += '<td class="Column' + j + ' cells_unq">' + i + '</td>';
            } else {
                var arr_cols = []
                $('.Column' + j).each(function() {
                    arr_cols.push(Number($(this).text()));
                });
                var num = exclude_num(arr_row, arr_cols);
                table_html += '<td class="Column' + j + ' cells_unq">' + num + '</td>';
            }

        }

        table_html += '</tr>';
        var row_html = $('#table_body').html();
        $('#table_body').html(row_html + table_html);
    }
    $('.cells_unq').each(function() {
        temp_text = $(this).text();
        $(this).text('Name' + temp_text);
    });
</script>
<style type="text/css">
    td {
        text-align: center;
    }
</style>

</html>

答案 2 :(得分:0)

OP希望创建一个审核矩阵,在该矩阵中随机选择被审核员工的姓名,审核者无法对其进行自我审核,并且该矩阵已针对46名员工完成。

基于先前的代码,此版本为每行构建一个员工姓名数组,其中审阅者的姓名不包括在该数组中。随机选择五个名称,并将其应用于审阅者。然后循环遍历46名员工中的每一个。

例如,在第一轮审阅中,从从中随机选择“受审者”的雇员数组中省略了“ name01”。在第二轮中,包括“ name01”,但从雇员数组中排除“ name02”。依此类推,以至于在每种情况下,用于随机选择五个评论的一组雇员总长为45个姓名,并且不包括评论者的姓名。

随机选择要评价的姓名并不能确保员工之间的评价均等和均匀分布。尽管每位员工将进行5次审核,但有些员工的审核次数超过5次,有些则少于5次,并且(取决于太阳,月亮和星星的排列)可能会选择一些而不进行审核

function s05648755803(){

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheetname = "Sheet3";
  var sheet = ss.getSheetByName(sheetname);

  // some variables
  var randomcount = 30; // how many random names
  var rowstart = 7; // ignore row 1 - the header row
  var width = 5;    // how many names in each row - 1/rater plus 5/ratee
  var thelastrow = sheet.getLastRow();
  //Logger.log("DEBUG:last row = "+thelastrow)

  // get the employee names
  var employeecount = thelastrow-rowstart+1;
  //Logger.log("DEBUG: employee count = "+employeecount);//DEBUG

  // get the data
  var datarange = sheet.getRange(rowstart, 1, thelastrow - rowstart+1);
  //Logger.log("DEBUG: range = "+datarange.getA1Notation());//DEBUG
  var data = datarange.getValues();
  //Logger.log("data length = "+data.length);
  //Logger.log(data);

  var counter = 0; 
  var newarray = [];
  for (c = 0;c<46;c++){
    counter = c;

    for (i=0;i<data.length;i++){    
      if(i!=counter){
        newarray.push(data[i]);
      }
    }

    //Logger.log(newarray);
    var rowdata = [];
    var results = selectRandomElements(newarray, 5);  
    Logger.log(results)
    rowdata.push(results);
    var newrange = sheet.getRange(rowstart+c, 3, 1, 5);
    newrange.setValues(rowdata);  

    // clear the arrays for the next loop
    var newarray=[]; 
    var rowdata = []
  }
}

/*
// selectRandomElements and getRandomInt
// Credit: Vidar S. Ramdal
// https://webapps.stackexchange.com/a/102666/196152
*/


function selectRandomElements(fromValueRows, count) {
  var pickedRows = []; // This will hold the selected rows
  for (var i = 0; i < count && fromValueRows.length > 0; i++) {
    var pickedIndex = getRandomInt(0, fromValueRows.length);
    // Pick the element at position pickedIndex, and remove it from fromValueRows. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
    var pickedRow = fromValueRows.splice(pickedIndex, 1)[0];
    // Add the selected row to our result array
    pickedRows.push(pickedRow);
  }
  return pickedRows;
}

function getRandomInt(min,
max) { // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
}

屏幕截图#1 Screenshot#1


屏幕截图#2 Screenshot#2