Dart不同类型列表查重异常:重复任务添加逻辑错误求助
Dart:批量添加未存在的重复任务到今日任务列表
背景
我有两个自定义类型的列表:
TodayTask类型集合:
todaysTodayTasks { task1 {title: "clean room", details: "dust, sweep, mop" ...} task1 {title: "shopping", details: "flour, carrots" ...} }
RepeatingTask类型集合,内部包含TodayTask属性:
repeatingTasks { task1 {repeatfreq:22, repeat:true, task: {title: "clean room", details: "dust, sweep, mop"} ... }, task1 {repeatfreq:52, repeat:true, task: {title: "shopping", details: "flour, carrots"} ... }, }
需求
检查todaysTodayTasks是否包含repeatingTasks中的task项,仅将未包含的项添加到todaysTodayTasks中。例如初始todaysTodayTasks只有clean room任务时,预期仅添加shopping任务。
现有问题
当todaysTodayTasks为空时功能正常,但列表已有项时,会错误添加repeatingTasks中除第一项外的所有项。
错误代码
if (todaysTodayTasks.isEmpty) { print("today tasks empty."); for (RepeatingTask task in repeatingTasks) { if (task.TodayTask != null) { print("ADD REPEATING TASK FOR TODAY: ${task.TodayTask!.title}"); //add task.TodayTask to todocolleciton here TodayTask newTodayTask = TodayTask( title: task.TodayTask!.title, details: task.TodayTask!.details, priority: task.TodayTask!.priority, isComplete: false, date: date, tags: task.TodayTask!.tags, isRepeating: true); writeTodoData(newTodayTask); } } }else{ for (RepeatingTask task in repeatingTasks) { for (TodayTask item in todaysTodayTasks) { print("Current TodayTask: ${item.title}"); print("Current Task: ${task.TodayTask!.title}"); if (task.TodayTask != null) { if (item.title != task.TodayTask!.title && item.details != task.TodayTask!.details) { print("ADD REPEATING TASK FOR TODAY: ${task.TodayTask!.title}"); //add task.TodayTask to todocolleciton here TodayTask newTodayTask = TodayTask( title: item.title, details: item.details, priority: item.priority, isComplete: false, date: date, tags: item.tags, isRepeating: true); writeTodoData(newTodayTask); } } } } }
结果差异
预期:仅添加未存在的任务;实际:重复添加多个任务(左侧为预期结果,右侧为实际结果)
问题根源
- 嵌套循环逻辑错误:对每个
RepeatingTask,遍历todaysTodayTasks时,只要有一个item与当前任务不匹配就执行添加操作,导致同一任务被多次插入。 - 任务属性赋值错误:创建
newTodayTask时错误使用了遍历到的item属性,而非repeatingTask中的TodayTask属性。 - 分支冗余:空列表与非空列表的处理逻辑可以合并,无需分开判断。
修正代码
// 提取已存在任务的唯一标识(用title+details组合作为判断依据) final existingTaskIdentifiers = todaysTodayTasks .map((task) => '${task.title}_${task.details}') .toSet(); for (final repeatingTask in repeatingTasks) { final targetTask = repeatingTask.TodayTask; if (targetTask == null) continue; final taskId = '${targetTask.title}_${targetTask.details}'; if (!existingTaskIdentifiers.contains(taskId)) { print("ADD REPEATING TASK FOR TODAY: ${targetTask.title}"); final newTodayTask = TodayTask( title: targetTask.title, details: targetTask.details, priority: targetTask.priority, isComplete: false, date: date, tags: targetTask.tags, isRepeating: true, ); writeTodoData(newTodayTask); // 更新已存在集合,避免重复处理 existingTaskIdentifiers.add(taskId); } }
优化说明
- 高效判断:用
Set存储已存在任务的唯一标识,判断操作复杂度从O(n)降为O(1),同时避免嵌套循环带来的O(n*m)时间消耗。 - 逻辑统一:无需区分列表是否为空,一套逻辑处理所有场景。
- 数据正确性:修复了任务属性赋值错误,确保添加的是
repeatingTask中的目标任务数据。 - 防重复处理:添加任务后同步更新
existingTaskIdentifiers,避免repeatingTasks中有重复项时重复添加。
内容的提问来源于stack exchange,提问作者XcOder
相关产品推荐
相关产品推荐

