Grade School
1. Readme
学级
根据学生的姓名以及他们所处的年级,为学校创建一个名册.
最后,你应该能够:
- 将学生的姓名添加到年级名册
- “Add Jim to grade 2.”
- “OK.”
- 获取所有注册年级的学生列表
- “哪个学生在二年级?”
- “We’ve only got Jim just now.”
- 获取所有年级所有学生的排序列表。年级应分为 1,2,3 级,年级中的学生应按名称按字母顺序排序。
- “谁现在都在学校就读?”
- “Grade 1: Anna, Barb, and Charlie. Grade 2: Alex, Peter, and Zoe. Grade 3…”
- “谁现在都在学校就读?”
请注意,我们所有学生只有一个名字.(这是一个小镇,你想要什么?)
加分
你是否通过了测试,且代码干净了?如果您愿意,可以尝试以下一些额外的事情:
- 如果您使用的语言具有可变数据结构,并且您的实现,会不会让外部代码,能直接改变学校的内部数据库,请查看是否可以阻止这种情况。随意尝试其他测试.
资源
与 gSchool 的 Phil Battos 进行配对http://gschool.it
2. 开始你的表演
pub struct School {} impl School { pub fn new() -> School { unimplemented!() } pub fn add(&mut self, grade: u32, student: &str) { unimplemented!("Add {} to the roster for {}", student, grade) } pub fn grades(&self) -> Vec<u32> { unimplemented!() } // If grade returned an `Option<&Vec<String>>`, // the internal implementation would be forced to keep a `Vec<String>` to lend out. // By returning an owned vector instead, // the internal implementation is free to use whatever it chooses. pub fn grade(&self, grade: u32) -> Option<Vec<String>> { unimplemented!("Return the list of students in {}", grade) } }
3. 测试代码查看
# #![allow(unused_variables)] #fn main() { fn some_strings(v: &[&str]) -> Option<Vec<String>> { Some(v.iter().map(|s| s.to_string()).collect()) } #[test] fn test_grades_for_empty_school() { let s = School::new(); assert_eq!(s.grades(), vec![]); } #[test] //#[ignore] fn test_grades_for_one_student() { let mut s = School::new(); s.add(2, "Aimee"); assert_eq!(s.grades(), vec![2]); } #[test] //#[ignore] fn test_grades_for_several_students_are_sorted() { let mut s = School::new(); s.add(2, "Aimee"); s.add(7, "Logan"); s.add(4, "Blair"); assert_eq!(s.grades(), vec![2, 4, 7]); } #[test] //#[ignore] fn test_grades_when_several_students_have_the_same_grade() { let mut s = School::new(); s.add(2, "Aimee"); s.add(2, "Logan"); s.add(2, "Blair"); assert_eq!(s.grades(), vec![2]); } #[test] //#[ignore] fn test_grade_for_empty_school() { let s = School::new(); assert_eq!(s.grade(1), None); } #[test] //#[ignore] fn test_grade_when_no_students_have_that_grade() { let mut s = School::new(); s.add(7, "Logan"); assert_eq!(s.grade(1), None); } #[test] //#[ignore] fn test_grade_for_one_student() { let mut s = School::new(); s.add(2, "Aimee"); assert_eq!(s.grade(2), some_strings(&["Aimee"])); } #[test] //#[ignore] fn test_grade_returns_students_sorted_by_name() { let mut s = School::new(); s.add(2, "James"); s.add(2, "Blair"); s.add(2, "Paul"); assert_eq!(s.grade(2), some_strings(&["Blair", "James", "Paul"])); } #[test] //#[ignore] fn test_add_students_to_different_grades() { let mut s = School::new(); s.add(3, "Chelsea"); s.add(7, "Logan"); assert_eq!(s.grades(), vec![3, 7]); assert_eq!(s.grade(3), some_strings(&["Chelsea"])); assert_eq!(s.grade(7), some_strings(&["Logan"])); } #}
4. 答案
# #![allow(unused_variables)] #fn main() { use std::collections::HashMap; pub struct School { grades: HashMap<u32, Vec<String>>, } impl School { pub fn new() -> School { School { grades: HashMap::new(), } } pub fn add(&mut self, grade: u32, student: &str) { let entry = self.grades.entry(grade).or_insert(Vec::new()); entry.push(student.to_string()); entry.sort(); } pub fn grades(&self) -> Vec<u32> { let mut s = self.grades.keys().cloned().collect::<Vec<u32>>(); s.sort(); s } pub fn grade(&self, grade: u32) -> Option<Vec<String>> { self.grades.get(&grade).map(|v| v.iter().cloned().collect()) } } #}