Dart中删除Map<int, String>元素后自动重新分配键的方法
Dart控制台待办列表:删除条目后自动调整键值
要实现删除待办条目后,后续条目的键自动连续递增(比如删第2项,原第3项键变为2),核心是删除指定条目后重新构建一个键从1开始连续的新Map,替换原有的toDoList。下面是具体的代码修改方案:
优化添加条目代码
你原来维护taskId的逻辑有点冗余,直接用toDoList.length + 1作为新条目的键就能保证序号连续,修改后的代码如下:
case 'c' : userInput = null; print('Enter name of new adventure'); print(''); String task = stdin.readLineSync()!; // 直接用当前长度+1作为新键,确保序号连续 int newTaskId = toDoList.length + 1; toDoList[newTaskId] = task; print('Quest added!'); for (final allPrint in mainMenu.entries) { print('${allPrint.key}: ${allPrint.value}'); } break; // 避免case穿透
修改删除条目代码
在删除指定条目后,添加逻辑重新整理键值,确保序号从1开始连续。具体步骤是:先按原键升序排序条目(保证顺序正确),再提取所有待办内容,最后重新生成键连续的Map:
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 (idDelete != null && toDoList.containsKey(idDelete)) { toDoList.remove(idDelete); print('Good Job!'); // 核心:删除后重新整理键值,保证序号连续 // 1. 按原键升序排序条目,确保顺序正确 var sortedEntries = toDoList.entries.toList()..sort((a, b) => a.key.compareTo(b.key)); // 2. 提取所有待办内容 List<String> tasks = sortedEntries.map((entry) => entry.value).toList(); // 3. 清空原Map,重新生成键从1开始的新Map toDoList.clear(); for (int i = 0; i < tasks.length; i++) { toDoList[i + 1] = tasks[i]; } // 打印主菜单 for (final allPrint in mainMenu.entries) { print('${allPrint.key}: ${allPrint.value}'); } } else { print('Invalid task ID!'); // 增加无效ID提示 } } break; // 避免case穿透
关键逻辑说明
- Dart的Map本身不会自动调整键的顺序和连续性,必须手动重新构建Map来实现序号连续。
- 先排序原条目是为了保证待办内容的顺序和删除前一致,避免乱序。
- 重新生成Map时用索引+1作为新键,确保序号从1开始连续递增。
内容的提问来源于stack exchange,提问作者Grace64
相关产品推荐
相关产品推荐

