I have some code that is generates an n set amount of random coordinates for [row,col] between 1-4. The problem is the same coordinates can be generated. What I need is if I declare n as 4. I need 4 unique coordinates and push them to array, here is my code that can produce duplicates:
function entriesToDel(n) {
var array = [];
for (var i = 0; i < n; i ) {
var row = Math.round(3*Math.random());
var col = Math.round(3*Math.random());
var coords = [row,col];
array.push(coords);
}
return array;
}
CodePudding user response:
Instead of creating the coordinates randomly, shuffle an array with all 3x3 coordinates and pick the first n of them:
function shuffle(a) { // Generic shuffle function
for (let i = a.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i 1));
let x = a[i];
a[i] = a[j];
a[j] = x;
}
return a;
}
function entriesToDel(n) {
// Generate all possible coordinates in a 3x3 grid
let coord = Array.from({length: 3}, (_, i) =>
Array.from({length: 3}, (_, j) => [i, j])
).flat();
// Shuffle and select
return shuffle(coord).slice(0, n);
}
console.log(entriesToDel(4));
CodePudding user response:
You can just change your for loop into a while loop, and just terminate when the array.length is equal to your parameter.
You can use Arrray.some()
to check if you already have the coordinate.
eg.
function entriesToDel(n) {
var array = [];
while (array.length < n) {
var row = Math.round(3*Math.random());
var col = Math.round(3*Math.random());
var coords = [row,col];
if (!array.some(([r,c]) =>
r === row && c === col))
array.push(coords);
}
return array;
}
console.log(entriesToDel(4));
CodePudding user response:
function entriesToDel(n) {
var array = [];
for (var i = 0; i < n; i ) {
var row = Math.round(3*Math.random());
var col = Math.round(3*Math.random());
var coords = [row,col];
if(array.includes(coords)){
i=i-1;
continue;
}
array.push(coords);
}
return array;
}
CodePudding user response:
I think a good approach is using a map (object). You can create an id for each coords array and check if you previously found it, then iterate n times.
function entriesToDel(n) {
var map = {};
while (i < n) {
var row = Math.round(3*Math.random());
var col = Math.round(3*Math.random());
var coords = [row,col];
var coordsId = `${row}${col}`;
if (!map[coordsId]) {
map[coordsId] = coords;
i ;
}
}
var array = Object.values(map);
return array;
}
CodePudding user response:
You can also try use my solution. I use new Map
to easly and fast get, set and check but you can use plain object instead of it
const entriesToDel = (coordsCount) => {
const coordsArr = [];
const coordsMap = new Map();
for (let i = 0; i < coordsCount; i) {
const row = Math.round(3 * Math.random());
const col = Math.round(3 * Math.random());
if (!coordsMap.has(row)) {
coordsMap.set(row, [col]);
coordsArr.push([row, col]);
} else {
const cols = coordsMap.get(row);
if (!cols.includes(col)) {
cols.push(col);
console.log(coordsMap);
coordsArr.push([row, col]);
continue;
}
--i;
}
}
return coordsArr;
}
console.log(entriesToDel(4));
CodePudding user response:
What you can do is simply put a condition based checking for the coords.
e.g. You can do something like,
function entriesToDel(n) {
var array = [];
for (var i = 0; i < n; i ) {
const repeat = () => {
var row = Math.round(3 * Math.random());
var col = Math.round(3 * Math.random());
var coords = [row, col];
let sameEntry = array.find(i => i[0] === row && i[1] === col)
if (sameEntry) {
repeat();
} else {
array.push(coords);
}
}
repeat();
}
console.log(array);
return array;
}