条件添加:putIfAbsent
本课属于 Coddy Dart 学习旅程的“逻辑与流程控制”单元。第 29 课,共 65 课。
有时,你需要向 Map 添加一个键值对,但前提是该键尚不存在。putIfAbsent() 方法可以完美处理这种情况:只有当映射中缺少该键时,才会添加该条目。
这个方法接受两个参数:要检查的键,以及键不存在时要添加的值。如果键已经存在,putIfAbsent() 不会执行任何操作,并保留现有值不变。如果键不存在,它会向映射中添加新的键值对。
Map<String, int> gameScores = {
'Alice': 150,
'Bob': 200
};
// 因为 Charlie 不在映射中,这会添加 Charlie。
gameScores.putIfAbsent('Charlie', () => 0);
print(gameScores); // {Alice: 150, Bob: 200, Charlie: 0}
// 因为 Alice 已经存在,这不会改变她的分数。
gameScores.putIfAbsent('Alice', () => 0);
print(gameScores); // {Alice: 150, Bob: 200, Charlie: 0}putIfAbsent() 方法特别适合用于初始化默认值,例如设置新用户账户,或在对某些键执行操作之前确保它们存在。这是一种安全添加数据的方式,可以避免意外覆盖已有信息。
挑战
简单创建一个程序来管理游戏锦标赛的报名系统,跟踪玩家分数,并确保所有玩家都有默认的初始值。你的程序应当:
- 读取一个表示锦标赛名称的字符串输入
- 读取多组输入,每组包含玩家姓名和当前分数(收到
"scores_done"时结束输入) - 读取多个字符串输入,表示想要参加锦标赛的新玩家(收到
"players_done"时结束输入) - 创建一个 Map,以玩家姓名作为键,以分数作为值
- 使用
putIfAbsent()方法为每位新玩家添加默认分数 0,但仅在他们尚未注册时添加 - 计算锦标赛统计数据,并严格按照下方所示的格式输出报名报告
例如,如果锦标赛名称是 "Spring Championship",已有分数包括 "Alice" 的 150、"Bob" 的 200、"Charlie" 的 75,新玩家是 "Diana"、"Alice"、"Eve",你的程序应输出:
Tournament: Spring Championship
Initial Scores: {Alice: 150, Bob: 200, Charlie: 75}
Registration Process:
Adding Diana: New player registered with score 0
Adding Alice: Player already exists, keeping score 150
Adding Eve: New player registered with score 0
Final Scores: {Alice: 150, Bob: 200, Charlie: 75, Diana: 0, Eve: 0}
Tournament Statistics:
Total registered players: 5
Players with scores above 0: 3
New players added: 2
Average score: 85.0
Status: Registration completed successfully如果锦标赛名称是 "Winter Cup",已有分数包括 "John" 的 300、"Mary" 的 250,新玩家是 "Sarah"、"Tom"、"John",你的程序应输出:
Tournament: Winter Cup
Initial Scores: {John: 300, Mary: 250}
Registration Process:
Adding Sarah: New player registered with score 0
Adding Tom: New player registered with score 0
Adding John: Player already exists, keeping score 300
Final Scores: {John: 300, Mary: 250, Sarah: 0, Tom: 0}
Tournament Statistics:
Total registered players: 4
Players with scores above 0: 2
New players added: 2
Average score: 137.5
Status: Registration completed successfully如果锦标赛名称是 "Summer League",已有分数包括 "Alex" 的 180、"Jordan" 的 220、"Taylor" 的 160、"Morgan" 的 190,新玩家是 "Casey"、"Riley",你的程序应输出:
Tournament: Summer League
Initial Scores: {Alex: 180, Jordan: 220, Taylor: 160, Morgan: 190}
Registration Process:
Adding Casey: New player registered with score 0
Adding Riley: New player registered with score 0
Final Scores: {Alex: 180, Jordan: 220, Taylor: 160, Morgan: 190, Casey: 0, Riley: 0}
Tournament Statistics:
Total registered players: 6
Players with scores above 0: 4
New players added: 2
Average score: 158.33333333333334
Status: Registration completed successfully你的程序必须使用 putIfAbsent() 方法为新玩家添加默认分数 0,确保现有玩家的当前分数保持不变。将所有分数的总和除以玩家人数,计算平均分。统计分数大于 0 的玩家人数,以及实际添加的新玩家人数(不包括已经注册的玩家)。输入格式为:锦标赛名称,然后是交替出现的玩家姓名和分数(以字符串形式输入,需要转换为整数),以 "scores_done" 结束,之后是以 "players_done" 结束的新玩家姓名。
亲手试试
import 'dart:io';
void main() {
// 读取锦标赛名称
String? tournamentName = stdin.readLineSync();
// 创建一个映射来存储玩家得分
Map<String, int> playerScores = {};
// 读取现有玩家的得分
while (true) {
String? input = stdin.readLineSync();
if (input == "scores_done") break;
String playerName = input!;
String? scoreInput = stdin.readLineSync();
int score = int.parse(scoreInput!);
playerScores[playerName] = score;
}
// 保存初始得分,以便显示
Map<String, int> initialScores = Map.from(playerScores);
// 读取要注册的新玩家
List<String> newPlayers = [];
while (true) {
String? input = stdin.readLineSync();
if (input == "players_done") break;
newPlayers.add(input!);
}
// TODO:在下方编写你的代码
// 使用 putIfAbsent() 方法添加新玩家,默认得分为 0
// 记录注册过程并计算统计数据
// 打印锦标赛注册报告
print("Tournament: $tournamentName");
print("Initial Scores: $initialScores");
print("Registration Process:");
// 在这里打印注册过程的详细信息
print("Final Scores: $playerScores");
print("Tournament Statistics:");
// 在这里打印统计数据
print("Status: Registration completed successfully");
}这节课包含一个小测验。开始学习即可作答,并记录你的进度。
逻辑与流程控制中的所有课
自己练习: Dart 在线编译器