【问题标题】:Google sheets mutually exclusive numerical order random number generator谷歌表格互斥数字顺序随机数生成器
【发布时间】:2020-01-18 13:54:30
【问题描述】:

有点拗口……我目前正在使用下面的脚本在单元格 I6:M6 中生成 1 到 200 之间的随机数。出于我的预期目的,这个脚本有两个问题(都不是主要问题,但我想要一些“润色”。

问题 1) 不互斥。这是最大的问题,因为五个数字中的每一个都必须是唯一的。重复发生的可能性不大,但确实发生时会有些烦人。

问题 2)我完全不知道如何或是否有可能生成这些随机数,然后按数字顺序放入 I6:M6 中,I6 是最小的。

我是一个完全的业余爱好者和 JavaScript(以及任何其他代码),我只是设法根据我在其他地方找到的信息拼凑起来,但我对它的工作原理有一个非常模糊的理解。

///////////////////////////////////////

function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [ {name:"Roll Dice",functionName:"rollDice"} ];
  sheet.addMenu("Script", entries);
};

function rollDice() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("sheet1 (New)");
    var cell = sheet.getRange("I6");
  cell.setValue( Math.floor((Math.random()*200)+1) );
    var cell = sheet.getRange("J6");
  cell.setValue( Math.floor((Math.random()*200)+1) );
    var cell = sheet.getRange("K6");
  cell.setValue( Math.floor((Math.random()*200)+1) );
    var cell = sheet.getRange("L6");
  cell.setValue( Math.floor((Math.random()*200)+1) );
    var cell = sheet.getRange("M6");
  cell.setValue( Math.floor((Math.random()*200)+1) );

};

///////////////////////////////////////

【问题讨论】:

    标签: javascript google-sheets


    【解决方案1】:

    为什么要编写脚本? I6 中的这个简单公式应该可以做到:

    =TRANSPOSE(SORT(SORTN(SEQUENCE(200),5,0,RANDARRAY(200),1)))
    

    【讨论】:

    • 也许我不明白。如果需要,很高兴扩展这个想法:)
    • SORTN() 是一个函数,允许您将一个数组按另一个数组排序,然后获取前 [n] 个结果。在我的例子中,我使用 SEQUENCE() 函数创建了一个数字 1 到 200 的数组。然后我问它按 RANDARRAY(200) 排序时的前 5 个结果。这只是 0 和 1 之间的 200 个随机数。然而,由于 Rand 数组是一个实时函数,因此每次编辑工作表时都会改变,这可能不是 Luke 特定场景的目标。不过,这可能对将来偶然发现此线程的其他人有所帮助。
    • 这是一个优雅的解决方案,比我最初的解决方案要好得多(在转向脚本之前我尝试了各种 RAND 函数),但是;您完全正确地建议我的方案需要更多控制 - 我的脚本在按钮按下时运行,并且绝对无法重新计算更改/分钟/小时。不过谢谢!
    【解决方案2】:

    我在 mainLoop 函数中添加了一个排序函数,现在应该按数字排序。

    function myFunction() {
      mainLoop()
    }
    
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = ss.getSheetByName("sheet1");
    
    function generateNumber(){
    return Math.floor((Math.random()*200)+1)
    }
    
    function setValue(_val, _address){
       var cell =  sheet.getRange(_address)
       cell.setValue(_val)
    }
    
    function generate(){
      var array = []
      while(array.length<5){
        var rand = generateNumber()
        var isUnique = array.indexOf(rand) === -1
        if(isUnique){
          array.push(generateNumber())
        }
    
      }
      return array
    }
    
    function mainLoop(){
        var array = generate()
          array.sort(function(a, b) {
      return a - b;
    });
        var addresses = ['I6','J6','K6','L6','M6']
        addresses.forEach(function (_address,_index){
            setValue(array[_index],_address)
        })
    }
    

    【讨论】:

    • 在检查它们是否唯一之前首先生成所有五个数字是不必要的,也不需要在迭代时使用递归......
    • 这个脚本也有类似的问题,生成随机数很好,但拒绝按数字顺序排列谢谢!
    • 我进行了编辑,应该可以按数字顺序对它们进行排序
    • @RaphaelCastro 您似乎在checkUnique() 中缺少return...
    • 功能完美,再次感谢。希望这个脚本也可以帮助其他人
    【解决方案3】:

    这样的事情应该可以解决问题。

    function onOpen() {
      var sheet = SpreadsheetApp.getActiveSpreadsheet();
      var entries = [{ name: "Roll Dice", functionName: "rollDice" }];
      sheet.addMenu("Script", entries);
    }
    
    function rollDice() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getSheetByName("sheet1 (New)");
      var numbers = [];
      while (numbers.length < 5) {
        var number = Math.floor(Math.random() * 200 + 1);
        if (numbers.indexOf(number) != -1) {
          numbers.push(number);
        }
      }
      numbers.sort((a, b) => a - b);
      ["I6", "J6", "K6", "L6", "M6"].forEach((addr, index) => {
        var cell = sheet.getRange(addr);
        cell.setValue(numbers[index]);
      });
    }
    

    【讨论】:

    • 谢谢 :) 19 上似乎存在语法错误,导致范围以非数字顺序出现?除非我需要改变一些我没有改变的东西......不过再次感谢!
    • @LukeFreeman 我仔细检查并没有看到语法错误...
    • @LukeFreeman 另外,添加了numbers.sort() 以对数字进行排序。 :)
    • @AKX 您需要将回调函数传递给 .sort() 函数,以便它按数字排序,没有回调它只会按字母顺序排序。
    【解决方案4】:

    你能导入randojs吗?如果是这样,您可以像这样轻松获得从 1 到 200 的有序唯一随机数数组:

    var sequence = randoSequence(1, 200).slice(0, 5).sort(function(a, b){return a-b});
    
    console.log(sequence);
    &lt;script src="https://randojs.com/1.0.0.js"&gt;&lt;/script&gt;

    因此,您可以将 rollDice() 函数更改为如下所示:

    function rollDice() {
      var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheet1 (New)");
      var sequence = randoSequence(1, 200).slice(0, 5).sort(function(a, b){return a-b});
      sheet.getRange("I6").setValue(sequence[0]);
      sheet.getRange("J6").setValue(sequence[1]);
      sheet.getRange("K6").setValue(sequence[2]);
      sheet.getRange("L6").setValue(sequence[3]);
      sheet.getRange("M6").setValue(sequence[4]);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-03
      相关资源
      最近更新 更多