I have a many files and I need to rename them with shuffle numbers.
Here is an example with 50 files (1 to 50) I found this code and I'am able to get the files renamed and put in a new folders ...
BUT some are not copied since their is some numbers that are generated twice. And if I run the script again and again, I get all my new 50 files but there is some that are duplicated.
const fs = require('fs');
for (let i = 1; i <= 50; i++) {
function getRandomNumber(min, max) {
let totalEle = max - min + 1;
let result = Math.floor(Math.random() * totalEle) + min;
return result;
}
function createArrayOfNumber(start, end) {
let myArray = [];
for (let i = start; i <= end; i++) {
myArray.push(i);
}
return myArray;
}
let numbersArray = createArrayOfNumber(1, 50);
let randomIndex = getRandomNumber(0, numbersArray.length - 1);
let randomNumber = numbersArray[randomIndex];
numbersArray.splice(randomIndex, 1);
fs.copyFile(`old/${i}.json`, `new/${randomNumber}.json`, (err) => {});
}
It's my first steps in js, I try to figure it out and I'm not... What can I do ?
The problem is that you are defining the functions and numbersArray in the loop, so you do it for every iteration, hence the numbers becoming duplicated. (So it's like you didn't remove the number from the numbersArray)
Here is a solution that I would use:
const fs = require('fs');
const numberOfFiles = 50;
// Create an array containing numbers from 1 to the numberOfFiles defined
let availableNumbers = Array.from({ length: numberOfFiles }, (v, k) => k + 1);
for (let i = 1; i < numberOfFiles; i++) {
let randomIndex = Math.floor(Math.random() * availableNumbers.length);
let randomNumber = availableNumbers[randomIndex];
fs.copyFile(`old/${i}.json`, `new/${randomNumber}.json`, (err) => { });
availableNumbers.splice(randomIndex, 1);
}
I needed to add a start index to norbot's solution
const fs = require("fs");
const startIndex = 1
const numberOfFiles = 5;
// Create an array containing numbers from 1 to the numberOfFiles defined
let availableNumbers = Array.from({ length: numberOfFiles }, (v, k) => k + 1);
for (let i = startIndex; i < startIndex + numberOfFiles; i++) {
let randomIndex = Math.floor(Math.random() * availableNumbers.length);
let randomNumber = availableNumbers[randomIndex];
fs.copyFile(`old/${i}.json`, `new/${randomNumber}.json`, (err) => { });
availableNumbers.splice(randomIndex, 1);
}
I tested and re-wrote your code. There are some things that would help it function as intended.
I moved your functions out of the code to prevent redefining the function each iteration of the loop.
I added an array alreadyHit which the function gerRandomNumber checks for the number already having been used. If it has already been used then we use some recursive logic to just call the function again. I added a bit of error testing to prevent an infinite loop if there are no more numbers left. Basically, if there are more than 100 attempts to make a random number, we throw an error.
Please ask if you have any questions 👍
const fs = require("fs");
const alreadyHit = [];
function getRandomNumber(min, max, attempts = 0) {
if (attempts > 100) throw new Error("Not enough numbers probably");
let totalEle = max - min + 1;
let result = Math.floor(Math.random() * totalEle) + min;
if (alreadyHit.includes(result)) return getRandomNumber(min, max, attempts + 1);
return result;
}
function createArrayOfNumber(start, end) {
let myArray = [];
for (let i = start; i <= end; i++) {
myArray.push(i);
}
return myArray;
}
const numbersArray = createArrayOfNumber(1, 50);
for (let i = 1; i <= 50; i++) {
const randomIndex = getRandomNumber(0, numbersArray.length - 1);
const randomNumber = numbersArray[randomIndex];
alreadyHit.push(randomIndex);
fs.copyFile(`./old/${i}.json`, `./new/${randomNumber}.json`, err => {
if (err) console.log("Error Found:", err);
});
}