A simple approach is to get all the ID values, sort them, then starting at 0 look for the first missing number in the sequence. That may be OK where efficiency doesn't matter, but a more efficient method is to:
- Get the IDs
- Sort them
- Step through the values to get the next available number
- Insert the value in the list of IDs
- Store the value so next time it starts at #3 from the previous value + 1
E.g.
class IDStore {
constructor(dataArray) {
if (!Array.isArray(dataArray)) {
return null;
}
this.previousIndex = 0;
this.indexes = dataArray.map(obj => obj.id).sort();
}
get nextIndex() {
while (this.indexes[this.previousIndex] == this.previousIndex) {
this.previousIndex++;
}
return this.previousIndex;
}
addIndex(index) {
if (!Number.isInteger(index) || this.indexes.find[index]) {
return null;
}
this.indexes.push(index);
this.indexes.sort();
return index;
}
}
var data = [ { id: 1 }, { id: 2 }, { id: 5 }, { id: 3 } ];
// Create an ID store
var idStore = new IDStore(data);
// Insert more objects in the array with unique IDs
for (var i=0, next; i<4; i++) {
// Current list of indexes
console.log('Indexes: ' + idStore.indexes);
// Get the next available index
next = idStore.nextIndex;
console.log('Next available: ' + next);
// Calling nextIndex doesn't affect next index
next = idStore.nextIndex;
console.log('Next available: ' + next);
// Use next index
data.push({id: next});
// Adding next index is manual
idStore.addIndex(next);
console.log('Added: ' + next);
}
// Data structure is independent
console.log('End: ' + JSON.stringify(data));
This is somewhat simplistic in that it assumes the IDs are sequential integers starting at 0 and doesn't have much validation or error handling.
Maintaining the id is separate from adding new members to the data array. It would be much better to combine the operations, so an "add object" method gets the next available ID, adds it to the object, adds the object to the array, updates the index and returns the new ID.