0

I have an array of 100 “XYCoordinate” objects, and I want to randomly select 25 of them and assign them to 25 "Cube" objects so I can present those cubes on the screen in different locations.

Obviously I need to make sure that I don’t accidentally randomly select the same XYCoordinate twice and assign it to two different Cube objects - cause then they’ll sit right on top of each other.

I thought the following code would work, but I’m still getting duplicates:

   // 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;
       }
   } 

Here’s where I call this function:

   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:
           . . .
       }
   } 

So what’s happening is that every time the selectRandomXYCoordinateObject function comes upon a duplicate - the App crashes!
The function does recognize when it’s got a duplicate on it's hands - and it does call itself again - but the makeCubes function seems to not be able to wait for that second execution. It seems as though it’s already moved along, and it's trying to display the tempCube at it's would-be coords.

I tried solving this using async and await but that didn't work - and I really don't wanna go barking up the Promises tree - just feels like I'm missing something here and that there should be a straight-forward solution...?

Sirab33
  • 1,247
  • 3
  • 12
  • 27
  • Might be cleaner to simply create a copy of the original Array and just splice each item from that copy every time. – Kaiido Feb 04 '21 at 03:21

1 Answers1

1

This is partly a guess, but you don't return the value that the recursive call to selectRandomXYCoordinateObject() returned:

       // 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();
       }

Instead of:

       // 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();
       }

So the first call to selectRandomXYCoordinateObject() returns undefined, and assuming you're trying to access properties of the returned object in the callee, you'll get a TypeError and crash.

Edit: By the way, this is not the best method to sample an array uniquely - see Unique (non-repeating) random numbers in O(1)?.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
  • Interesting - it's not crashing anymore - but it's STILL giving me duplicates. Very weird... – Sirab33 Feb 04 '21 at 02:57
  • No. That's what I'm saying: it's not crashing anymore. It's RUNNING ok - BUT, it's still giving me duplicates. – Sirab33 Feb 04 '21 at 03:12
  • Maybe there are duplicates in the coords array? – Chayim Friedman Feb 04 '21 at 03:13
  • Yeah I was just starting to look at that... I'll let you know – Sirab33 Feb 04 '21 at 03:16
  • OK - what you suspected - and what I suspected - was indeed true: I had duplicates in my coords array (which actually has 10,000 coordinate objects, not 100!) I generated them algorithmically, 2500 per each quadrant, so yes, I had duplicates. And your suggestion to use `return` works! Thank you! – Sirab33 Feb 04 '21 at 03:51