Creating unique random IDs can be a pretty complex task, and there are dedicated libraries like uuid
that can handle this for you.
But sometimes, those IDs can end up being pretty long, with timestamps and other details involved. And that's great when you need it. But sometimes, you just need a short unique ID.
And maybe you don't want to use another JavaScript library for it.
For example, I was recently putting together a quick quiz, and I need each of the answer options to have unique IDs.
Since these IDs are generated on the front end, I didn't want to use a dedicated ID library to achieve it. And since there were only going to be 2-10 options per question, I didn't need those IDs to be very long either. I was thinking something like this:
let options = {
"a": "An option",
"b": "Another option.",
"c": "A different option",
"d": "You get the idea...",
};
let answer = "d";
So let's do this!
Create a random ID with JavaScript (of custom length!)
We can start by creating a random ID - and worry about it being unique later.
// short random string for ids - not guaranteed to be unique
const randomId = function(length = 6) {
return Math.random().toString(36).substring(2, length+2);
};
The function works by creating a random number (Math.random()
), which gives us a decimal number between 0 and 1.
Then we convert the number to a string with a radix of 36 toString(36)
. This radix represents digits beyond 0-9 with letters, so the random number is converted to a random string.
Finally, we cut off the 0.
at the start of the decimal number, and end the string at our length
argument .substring(2, length+2)
- (+2 for the 2 characters we lost at the start of string!).
Now we can call the randomId
function and get an ID that's 6 characters, but you can also pass a length (up to 10*) if you want a shorter or longer ID.
randomId(); // 'q9anz4'
randomId(2); // '5b'
randomId(10); // '68xclia3s8'
If you want to go up to lengths of 20 you could do return (Math.random().toString(36).substring(2) + Math.random().toString(36).substring(2)).substring(0, length);
.
Now you should get a random ID each time you call randomId
, to the length of your choice - but it's not guaranteed to be unique.
Checking if the ID already exists
Let's expand the function to make sure the ID we get is unique. After all, an ID must be unique. In this case, if I had two properties with the same ID, the second one would remove the first (since I am using the IDs for object keys).
Now you can do fancy things like adding a timestamp, but it still doesn't guarantee uniqueness if you make lots of IDs at the same time. That's not an issue in this case, but it would result in longer IDs, and I want to avoid that.
Instead, because I know the other IDs, I can check if the ID already exists in an array of existing IDs, like this:
let existing = [ "q9anz4", "avd83n", "i2r37d", "jk3eum"]
let newId = randomId();
existing.find(function(id) {
return id === newId;
});
If the ID is found in the existing array, then the find method will return it, if not, you get undefined. So we can create a function to check if an ID is unique like this:
// check if the id matches any other existing ids provided as an array
const checkId = function(id, existing = []) {
let match = existing.find(function(item) {
return item === id;
});
return match ? false : true;
};
Creating a unique random ID
Now we can create an ID and check if it already exists - it's finally time for us to create a unique random ID!
// generate a unique id
const getId = function({ length, existing = [] }) {
const limit = 100; // max tries to create unique id
let attempts = 0; // how many attempts
let id = false;
while(!id && attempts < limit) {
id = randomId(length); // create id
if(!checkId(id, existing)) { // check unique
id = false; // reset id
attempts++; // record failed attempt
}
}
return id; // the id or false if did not get unique after max attempts
};
Ok, this function uses our randomId
function and the checkId
function we made earlier, to create a unique id. You can (optionally) pass it the length
property, and also an array of existing IDs, and it will give you a new unique ID in return.
The while
loop will keep creating a new ID until a unique one is found (or you run out of attempts!).
I've given it a limit of 100 because truthfully if it can't create a unique ID after 100 attempts, you can either increase the length or consider using a more dedicated library.
Here's how I would use this function to create a new unique ID for the quiz options example we started with.
let options = {
"12e": "An option",
"ufh": "Another option.",
"psr": "A different option",
};
let newId = getId({ length: 3, existing: Object.keys(options) }); // 'a9b'
if (newId) {
options[newId] = "A new option";
} else {
throw new Error('Could not create unique ID!');
}