package date_20250415

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

/** 计算学生成绩平均分 */
object RDDAverageScore {

  def main(args: Array[String]): Unit = {

    // 创建SparkConf对象，存储应用程序的配置信息
    val conf = new SparkConf()
      .setMaster("local") // 启动本地化计算
      .setAppName("Spark-AverageScore") // 设置应用程序名称

    // 创建SparkContext对象
    val sc = new SparkContext(conf)

    // 读取每个科目的成绩文件
    val mathRDD: RDD[String] = sc.textFile("hdfs://hadoop102:8020/input/data/math.txt")
    val chineseRDD: RDD[String] = sc.textFile("hdfs://hadoop102:8020/input/data/chinese.txt")
    val englishRDD: RDD[String] = sc.textFile("hdfs://hadoop102:8020/input/data/english.txt")

    // 处理每个科目RDD，将每一行数据转化为 (姓名, 分数) 二元组
    val mathScores: RDD[(String, Int)] = mathRDD.map(line => {
      val Array(name, score) = line.split(" ")
      (name, score.toInt)
    })

    val chineseScores: RDD[(String, Int)] = chineseRDD.map(line => {
      val Array(name, score) = line.split(" ")
      (name, score.toInt)
    })

    val englishScores: RDD[(String, Int)] = englishRDD.map(line => {
      val Array(name, score) = line.split(" ")
      (name, score.toInt)
    })

    // 合并三个RDD
    val allScores: RDD[(String, Int)] = mathScores.union(chineseScores).union(englishScores)

    // 对每个学生的所有分数进行聚合 (姓名, (总分, 科目数))
    val studentScores: RDD[(String, (Int, Int))] = allScores
      .map( x => (x._1,(x._2,1)))
      .reduceByKey { case ((sum1, count1), (sum2, count2)) =>
        (sum1 + sum2, count1 + count2)
      }

    // 计算平均分 (姓名, 平均分)
    val averageScores: RDD[(String, Int)] = studentScores.mapValues { case (sum, count) =>
      sum / count
    }

    // 保存结果到HDFS
//    averageScores.saveAsTextFile("hdfs://192.168.182.100:9000/output/averageScore")

    // 打印平均分结果
    averageScores.collect().foreach { case (name, avgScore) =>
      println(s"$name $avgScore")
    }

    // 停止SparkContext
    sc.stop()
  }
}