【问题标题】:Javascript - how to prevent duplicates when randomly selecting from ArrayJavascript - 从数组中随机选择时如何防止重复
【发布时间】:2021-05-08 08:07:07
【问题描述】:

我有一个包含 100 个 “XYCoordinate” 对象的数组,我想随机选择其中的 25 个并将它们分配给 25 个 “Cube” 对象,这样我就可以呈现屏幕上不同位置的那些立方体。

显然我需要确保我不会意外地随机选择相同的 XYCoordinate 两次并将其分配给两个不同的 Cube 对象 - 因为它们会坐彼此重叠。

我认为下面的代码可以工作,但我仍然得到重复:

   // I first declare an array to store the randomly selected XYCoordinate objects:
   var selectedCoordObjectsArray = [];

   // I then declare a second array to store just the INDEXES of the Coords that 
   // were already randomly selected:
   var selectedCoordIDNumbersArray = [];
    
        
   // Next I make a function to randomly select one XYCoordinate object:
   function selectRandomXYCoordinateObject() {
       let randomCoordNumber = Math.floor(Math.random() * 100);

       // Check if this Coord-number was already selected:
       if(selectedCoordIDNumbersArray.includes(randomCoordNumber)) {
           // A Coord of this ID was already selected!
           console.log(“Duplicate!”);
           // Immediately call this function again:
           selectRandomXYCoordinateObject();
       }
       else { 
          // Grab this Coord from my previously declared “coordsArray”:
          let chosenCoord = coordsArray[randomCoordNumber];
          // Add the INDEX of this Coord to the “selectedCoordIDNumbersArray”:
          selectedCoordIDNumbersArray.push(randomCoordNumber);
          // Finally, return the actual “chosenCoord” object: 
          return chosenCoord;
       }
   } 

这里是我调用这个函数的地方:

   function makeCubes() {
       for(var cubeCounter = 0; cubeCounter < 25; cubeCounter++) {
          let tempCube = cubesArray[cubeCounter];
          // prep the Cube, give it different Width & Height, Color, etc. 
          // Then, assign to it a random coordinate: 
          tempCube.coords = selectRandomXYCoordinateObject();
            
          // an then display the “tempCube” at those coords:
           . . .
       }
   } 

所以发生的情况是,每次 selectRandomXYCoordinateObject 函数出现重复时 - 应用程序崩溃!
函数确实可以识别,当它的手上有一个副本时 - 它确实会再次调用自己 - 但 makeCubes 函数似乎没有能够等待第二次执行。似乎它已经移动了,它正试图以它可能的坐标显示tempCube

我尝试使用 asyncawait 来解决这个问题,但这没有用 - 我真的不想在 Promises 树上狂吠 - 只是觉得我在这里和那里遗漏了一些东西应该是一个直接的解决方案...?

【问题讨论】:

  • 简单地创建原始数组的副本并每次从该副本中拼接每个项目可能会更干净。

标签: javascript arrays random duplicates


【解决方案1】:

这部分是猜测,但您没有返回对selectRandomXYCoordinateObject() 的递归调用返回的值:

       // Check if this Coord-number was already selected:
       if(selectedCoordIDNumbersArray.includes(randomCoordNumber)) {
           // A Coord of this ID was already selected!
           console.log(“Duplicate!”);
           // Immediately call this function again:
           selectRandomXYCoordinateObject();
       }

代替:

       // Check if this Coord-number was already selected:
       if(selectedCoordIDNumbersArray.includes(randomCoordNumber)) {
           // A Coord of this ID was already selected!
           console.log(“Duplicate!”);
           // Immediately call this function again:
           return selectRandomXYCoordinateObject();
       }

所以对selectRandomXYCoordinateObject() 的第一次调用会返回undefined,并且假设您尝试在被调用者中访问返回对象的属性,您将得到TypeError 并崩溃。

编辑:顺便说一句,这不是唯一采样数组的最佳方法 - 请参阅Unique (non-repeating) random numbers in O(1)?

【讨论】:

  • 有趣 - 它不再崩溃 - 但它仍然给我重复。很奇怪……
  • 没有。这就是我要说的:它不再崩溃了。它运行正常 - 但是,它仍然给我重复。
  • 也许 coords 数组中有重复项?
  • 是的,我刚开始看那个...我会告诉你的
  • 好的——你怀疑的——和我怀疑的——确实是真的:我的坐标数组中有重复项(实际上有 10,000 个坐标对象,而不是 100 个!)我通过算法生成它们,每个 2500 个象限,所以是的,我有重复。您使用return 的建议有效!谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-07-02
  • 1970-01-01
  • 2015-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-27
  • 1970-01-01
相关资源
最近更新 更多