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())
   }
}

#}



填充/相关