再多学一点吧

导航

Scala语法2

练习

package scala_01.practice

import org.junit.{Before, Test}

import scala.collection.immutable
import scala.collection.immutable.StringOps
import scala.collection.mutable.ListBuffer
import scala.io.Source

/**
  * 1、统计班级人数
  * 2、统计学生的总分
  */

class Practice1 {

  var students: List[Student] = _
  var score: List[Score] = _
  var cource: List[Cource] = _

  @Before
  def read_file(): Unit = {
    // 读取students.txt数据
    // 这里路径不能是   scala/data/students.txt
    students = Source.fromFile("data/students.txt")
      .getLines()
      .toList
      .map(s => {
        val spilts: Array[String] = s.split(",")
        val id: String = spilts(0)
        val name: String = spilts(1)
        val age: Int = spilts(2).toInt
        val gender: String = spilts(3)
        val clazz: String = spilts(4)
        Student(id, name, age, gender, clazz)
      })

    // 读取Score.txt数据
    score = Source.fromFile("data/score.txt")
      .getLines()
      .toList
      .map(s => {
        val splits: Array[String] = s.split(",")
        val id: String = splits(0)
        val sub_id: String = splits(1)
        val score_sc: Int = splits(2).toInt
        Score(id, sub_id, score_sc)
      })

    // 读取Cource.txt数据
    cource = Source.fromFile("data/cource.txt")
      .getLines()
      .toList
      .map(s => {
        val splits: Array[String] = s.split(",")
        val sub_id: String = splits(0)
        val sub_name: String = splits(1)
        val score_max: Int = splits(2).toInt
        Cource(sub_id, sub_name, score_max)
      })


  }

  @Test
  def printAll: Unit = {
    students.take(10).foreach(println)
    score.take(10).foreach(println)
    cource.take(10).foreach(println)
  }

  //  1、统计班级人数
  @Test
  def count_students: Unit = {
    val count_stu: Map[String, Int] = students
      .groupBy(s => s.clazz)
      .map(kv => (kv._1, kv._2.size))
    count_stu.foreach(println)

  }

  //  2、统计学生的总分
  @Test
  def sum_score: Unit = {
    val sum_sc: Map[String, Int] = score.groupBy(s => s.id)
      .map(kv => {
        val id: String = kv._1
        val score_sc: List[Score] = kv._2
        val sum_s = score_sc.map(s => s.score_sc).sum
        (id, sum_s)
      })

    sum_sc.foreach(println)
  }

  @Test
  //  1、统计年级排名前十学生各科的分数 [学号,学生姓名,学生班级,科目名,分数]
  def um_score_top10_stu: Unit = {

    //先拿到排名前十的学生id
    val top10ids: List[String] = score.groupBy(s => s.id)
      .map(kv => {
        val id: String = kv._1
        val score_sc: List[Score] = kv._2
        val sum_s = score_sc.map(s => s.score_sc).sum
        (id, sum_s)
      }).toList
      .sortBy(s => (-s._2)) // 按照总分倒序排列
      .take(10)
      .map(s => s._1) // 直接取出id


    // 将score转成kv格式的Map集合
    // 将id作为key Score对象作为value
    val scomap: Map[String, List[(String, Score)]] = score.map(kv => {
      val id: String = kv.id
      val values: Score = kv
      (id, values)
    }).groupBy(kv => kv._1)


    // 将cource_id作为key cource_name作为value 构建subMap
    val submap: Map[String, String] = cource.map(s => (s.sub_id, s.sub_name)).toMap


    val result: List[(String, String, String, String, Int)] = students.filter(s => {
      top10ids.contains(s.id)
    }).flatMap(s => {
      // 初始化一个ListBuffer用于保留最后的结果
      // ListBuffer中每个元素的类型是一个5元组(同题目需要的5列结果类型一一对应)

      val tuples: ListBuffer[(String, String, String, String, Int)] = ListBuffer[(String, String, String, String, Int)]()
      val id: String = s.id
      val name: String = s.name
      val clazz: String = s.clazz
      // 根据学生id从scoMap中将该学生的6门科目的分数取出来 得到一个Score对象构成的List
      val scores: List[Score] = scomap(s.id).map(_._2)
      // 遍历每个学生的6门科目成绩
      scores.map(sco => {
        val sub_id: String = sco.sub_id
        val score_sc: Int = sco.score_sc
        // 根据科目id从subMap中取出科目名称
        val sub_name: String = submap(sub_id)
        tuples.append((id, name, clazz, sub_name, score_sc))
      })
      tuples
    })
    result.foreach(println)
  }


  // 2、统计总分大于年级平均分的学生 [学号,姓名,班级,总分]
  @Test
  def sum_score_beyond_avg: Unit = {


    // 年级的总分拿过来
    val sum_sc: Map[String, Int] = score.groupBy(s => s.id)
      .map(kv => {
        val id: String = kv._1
        val score_sc: List[Score] = kv._2
        val sum_s = score_sc.map(s => s.score_sc).sum
        (id, sum_s)
      })
    // 计算年级平均分
    val bigsum: Int = sum_sc.map(_._2).sum
    val avg: Double = bigsum / (sum_sc.size.toDouble)
    println(avg)

    // 以学生id作为key Students对象最为value 构建stuMap
    val stumap: Map[String, Student] = students.map(s => (s.id, s)).toMap

    sum_sc.filter(kv => kv._2 > avg) // 过滤出成绩大于年级平均分的学生
      .map(kv => {
      val id: String = kv._1
      val sum_ss: Int = kv._2
      // 根据学生id从stuMap中提取出学生信息
      val stu: Student = stumap(id)
      val name: String = stu.name
      val clazz: String = stu.clazz
      (id, name, clazz, sum_ss)
    }).foreach(println)

  }

  //  3、统计每科都及格的学生 [学号,姓名,班级,科目,分数]
  @Test
  def every_subject_pass: Unit = {
    // 每门科目的及格分数Map
    // k:科目id  v:二元组(科目名称,科目及格分数)
    val sub_pass_map: Map[String, (String, Double)] = cource.map(s => {
      val id: String = s.sub_id
      val sub_name: String = s.sub_name
      val pass_score: Double = (s.score_max) * 0.6
      (id, (sub_name, pass_score))
    }).toMap


    // 所有6门科目都及格的学生id
    val pass_id: List[String] = score
      .filter(s => s.score_sc > sub_pass_map(s.sub_id)._2)
      .groupBy(kv => kv.id)
      .map(kv => (kv._1, kv._2.size))
      .filter(s => s._2 == 6)
      .map(s => s._1)
      .toList


    val groupsc: Map[String, List[(String, Score)]] = score.map(s => (s.id, s)).groupBy(_._1)

    students.filter(s => pass_id.contains(s.id))
      .map(s => {
        val lb: ListBuffer[(String, String, String, String, Int)] = ListBuffer[(String, String, String, String, Int)]()

        val id: String = s.id
        val name = s.name
        val clazz = s.clazz


        // 根据学生id从scoMap中将该学生的6门科目的分数取出来 得到一个Score对象构成的List
        val scores: List[Score] = groupsc(id).map(_._2)
        // 遍历每个学生的6门科目成绩
        scores.map(s => {
          val score_sc: Int = s.score_sc
          val sub_id: String = s.sub_id
          val sub_name: String = sub_pass_map(sub_id)._1

          lb.append((id, name, clazz, sub_name, score_sc))

        })
        lb

      }).foreach(println)

  }


  @Test
  // 4、统计每个班级的前三名 [学号,姓名,班级,分数]
  def clazz_sum_score_top3: Unit = {

    // 学生总分
    val id_sum_core: Map[String, Int] = score.groupBy(s => s.id)
      .map(kv => {
        val id: String = kv._1
        val sum_sc: Int = kv._2.map(s => s.score_sc).sum
        (id, sum_sc)
      })




    // 根据学生id 从id_sum_score中获取学生总分
    students.map(s => (s.id, s.name, s.clazz, id_sum_core(s.id)))
      .groupBy(s => s._3)
      .flatMap(kv => {
        val clazz: String = kv._1
        val stuList: List[(String, String, String, Int)] = kv._2
        val top3: List[(String, String, String, Int)] = stuList.sortBy(s => s._4)
          .take(3)

        top3
      }).foreach(println)


  }

  // 5、统计偏科最严重的前100名学生  [学号,姓名,班级,科目,分数]
  @Test
  def unbalanceTop100: Unit ={

    val cour_map: Map[String, Int] = cource.map(s => {
      val sub_id: String = s.sub_id
      val score_max: Int = s.score_max
      (sub_id, score_max)
    }).toMap

    //每个学生的百分制分数
    val per_score: List[(String, Double)] = score.map(s => {
      val id: String = s.id
      val score_sc: Int = s.score_sc
      val sub_id: String = s.sub_id
      val score_max: Int = cour_map(sub_id)
      val per_sco: Double = (score_sc / score_max.toDouble) * 100
      (id, per_sco)
    })




    //学生平均分
    val stu_avg: Map[String, Double] = per_score.groupBy(s => s._1)
      .map(kv => {
        val id: String = kv._1
        val values: List[(String, Double)] = kv._2
        val sum: Double = values.map(s => s._2).sum
        val avg: Double = sum / values.size.toDouble
        (id, avg)
      })

    // 求100位方差
    val top100: List[String] = per_score.map(kv => {
      val id: String = kv._1
      val per_sco: Double = kv._2
      val avg: Double = stu_avg(id)
      val fenzi: Double = math.pow((avg - per_sco), 2)
      (id, fenzi)
    }).groupBy(_._1)
      .map(kv => {
        val id: String = kv._1
        val size: Int = kv._2.size
        val fancha: Double = kv._2.map(_._2).sum / size
        (id, fancha)
      }).toList
      .sortBy(-_._2)
      .map(_._1)
      .take(100)







    val cou_map: Map[String, String] = cource.map(s=>(s.sub_id,s.sub_name)).toMap


    val sco_map: Map[String, List[Score]] = score.groupBy(_.id)




    students.filter(s=>top100.contains(s.id))
      .flatMap(s=>{

        val tuples: ListBuffer[(String, String, String, String, Int)] = ListBuffer[(String,String,String,String,Int)]()
        val id: String = s.id
        val name: String = s.name
        val clazz: String = s.clazz


        sco_map(id).foreach(s=>{
          val sub_id: String = s.sub_id
          val score_sc: Int = s.score_sc
          val sub_name: String = cou_map(sub_id)
          tuples.append((id,name,clazz,sub_name,score_sc))

        })

        tuples

    }).foreach(println)





















  }


  case class Student(id: String, name: String, age: Int, gender: String, clazz: String)

  case class Score(id: String, sub_id: String, score_sc: Int)

  case class Cource(sub_id: String, sub_name: String, score_max: Int)

}









posted on 2021-11-10 22:53  糟糟张  阅读(76)  评论(0编辑  收藏  举报