Reputation: 13
I'm new to programming and taking a course in dart. I'm trying to build a to-do list console program and I'm using a map as the to-do list. I'm trying to figure out how to automatically assign the key so that when I delete an entry the following keys would change accordingly (for example, deleting the second entry and having the key of the former third entry change to 2 and so on).
How should I go about it?
This is my code so far for adding an entry:
int taskId = toDoList.length;
case 'c' :
userInput = null;
print('Enter name of new adventure');
print('');
if (taskId >= toDoList.length) {
++taskId;
}
String task = stdin.readLineSync()!;
toDoList[taskId] = task;
print('Quest added!');
for (final allPrint in mainMenu.entries) {
print('${allPrint.key}: ${allPrint.value}');
} ;
And this is my code for deleting an entry:
case 'b' :
userInput = null;
if (toDoList.length < 1) {
print('No quests available to complete!');
for (final allPrint in mainMenu.entries) {
print('${allPrint.key}: ${allPrint.value}');
};
} else{
print('Which good fortune have you brought from your adventures?');
print('Which task have you completed?');
print('');
for (final allPrint in toDoList.entries) {
print('${allPrint.key}: ${allPrint.value}');
}
print('');
print('');
int? idDelete = int.tryParse(stdin.readLineSync() ?? '');
if (toDoList.containsKey(idDelete)) {
toDoList.remove(idDelete);
print('Good Job!');
for (final allPrint in mainMenu.entries) {
print('${allPrint.key}: ${allPrint.value}');
} ;
}
}
Upvotes: 1
Views: 31
Reputation: 11531
What you have here is equivalent of an autoincrement feature in database engines, such as PostgreSQL. When you add a row into a database table with an autoincrement column, that column (often called the ID) starts with 0 and goes on until the limit of the defined datatype. However, if the second row added is removed from a table with 20 rows, the database will not reindex all 18 following elements, because it'll be very inefficient: what if the table has 200 rows?
Anyway, you would need something like this:
todoList.remove(keyToRemove);
// Reindex all items
final Map<int, String> newTodoList = {};
int newIndex = 1;
todoList.forEach((key, value) {
newTodoList[newIndex] = value;
newIndex++;
});
todoList.clear();
todoList.addAll(newTodoList);
What can be done in this case is to hide the ID for the user, and when you need to display the map, just sort the map entries by key:
void main() {
Map<int, String> todoList = {
1: 'Buy groceries',
3: 'Finish homework',
// ...
18: 'Clean the house',
19: 'Call mom',
20: 'Go for a run',
};
// Displaying by key will show holes in the map
for (final entry in todoList.entries) {
print('${entry.key}: ${entry.value}');
}
// 1: Buy groceries
// 3: Finish homework
// 4: Read a book
// ...
// 18: Clean the house
// 19: Call mom
// 20: Go for a run
// Instead, use the key only to sort the entries
final List<MapEntry<int, String>> entries = todoList.entries.toList();
entries.sort((e0, e1) => e0.key.compareTo(e1.key));
for (int i = 0; i < entries.length; i++) {
final e = entries[i];
print('${i+1}: ${e.value}');
}
// 1: Buy groceries
// 2: Finish homework
// 3: Read a book
// ...
// 17: Clean the house
// 18: Call mom
// 19: Go for a run
}
But note that, whenever you need to display the map, you'll have to sort all the items beforehand.
So you have two problems while using a map: reindex all elements when removing an element (the logic will become more complex if you decide to remove more than one element), or sorting all elements when displaying the map.
Basically, a Map<int, String>
is not a good choice here.
Note that every key in your map strictly goes from 1 (the first element index) to N (the last element index). Therefore, while you could use a map to represent your TODO list, it's a best practice to use a plain List<String>
instead, which uses indices that goes from 0 to N-1:
List<String> todoList = [];
// Adding elements:
todoList.add('Buy groceries');
todoList.add('Pay bills');
todoList.add('Finish homework');
// ...
todoList.add('Clean the house');
todoList.add('Call mom');
todoList.add('Go for a run');
// To remove the N item, refer to the N-1 position:
todoList.remove(1); // The second element
// No need to reindex the following elements:
// Dart already implements that for you
print(todoList);
// [
// Buy groceries,
// Finish homework,
// Read a book,
// ...
// Clean the house,
// Call mom,
// Go for a run,
// ]
// Or, if you need to display the position:
for (int i = 0; i < todoList.length; i++) {
print('${i+1}: ${todoList[i]}');
}
Upvotes: 1