KMP 实现鸿蒙跨端:Kotlin 成绩排行榜生成与分析工具
本文介绍了一个基于Kotlin Multiplatform (KMP)的成绩分析工具实现方案。该工具接收"姓名 分数"格式的输入数据,输出包含排行榜、基础统计、分数段分析和综合评语的详细报告。核心技术路径为Kotlin→Kotlin/JS→JavaScript模块→ArkTS页面调用,体现了"算法在Kotlin,界面在ArkTS"的开发模式。Kotlin核心
目录
- 概述
- 功能设计
- Kotlin 实现代码(KMP)
- JavaScript 编译输出与类型定义
- ArkTS 页面集成与调用
- 交互示例
- 编译与自动复制流程
- 总结
概述
本案例在 Kotlin Multiplatform (KMP) 工程中实现了一个成绩排行榜生成与分析工具:
- 输入:一串“姓名 分数”的列表,例如:
张三 95, 李四 88, 王五 76 - 输出:
- 排名列表(第 N 名、分数、相对平均分)
- 基础统计(人数、最高分、最低分、平均分)
- 分数段统计(优秀/良好/及格/不及格人数及占比)
- 综合评语
- 技术路径:Kotlin → Kotlin/JS → JavaScript 模块 → ArkTS 页面调用
这是继 BMI 体质指数计算器、贷款等额本息还款计算器 之后的第三个完整链路案例,继续体现“算法在 Kotlin,界面在 ArkTS”的模式。
功能设计
输入格式:
张三 95, 李四 88, 王五 76
设计要点:
- 使用逗号分隔多位同学,空格分隔姓名与成绩
- 兼容一定程度的空格与格式误差(trim 处理)
- 对解析失败或格式不正确给出友好错误提示
分析内容:
- 排行榜:按分数从高到低排序,给出名次、分数以及相对平均分的差值
- 基础统计:总人数、最高分、最低分、平均分
- 分段统计:
- 优秀:
>= 90 - 良好:
80 - 89 - 及格:
60 - 79 - 不及格:
< 60
- 优秀:
- 综合评语:根据平均分给出整体表现评价
Kotlin 实现代码(KMP)
在 src/jsMain/kotlin/App.kt 中新增 scoreRankingAnalyzer 方法,并通过 @JsExport 导出:
@OptIn(ExperimentalJsExport::class)
@JsExport
fun scoreRankingAnalyzer(inputText: String = "张三 95, 李四 88, 王五 76"): String {
// 输入格式: "姓名 分数, 姓名 分数, ..."
if (inputText.trim().isEmpty()) {
return "❌ 错误: 输入不能为空\n请输入类似 '张三 95, 李四 88' 的内容"
}
// 解析为 (姓名, 分数)
val entries = inputText.split(",")
.map { it.trim() }
.filter { it.isNotEmpty() }
.mapNotNull { part ->
val pieces = part.split(" ").filter { it.isNotEmpty() }
if (pieces.size < 2) return@mapNotNull null
val name = pieces[0]
val score = pieces[1].toDoubleOrNull() ?: return@mapNotNull null
name to score
}
if (entries.isEmpty()) {
return "❌ 错误: 没有解析到有效的姓名和分数\n示例: 张三 95, 李四 88, 王五 76"
}
// 排序
val sorted = entries.sortedByDescending { it.second }
// 基础统计
val scores = sorted.map { it.second }
val count = scores.size
val max = scores.maxOrNull() ?: 0.0
val min = scores.minOrNull() ?: 0.0
val avg = if (count > 0) scores.sum() / count else 0.0
// 分段统计
val excellent = scores.count { it >= 90 }
val good = scores.count { it in 80.0..89.999 }
val pass = scores.count { it in 60.0..79.999 }
val fail = scores.count { it < 60.0 }
// 排行榜文本
val rankingLines = sorted.mapIndexed { index, (name, score) ->
val rank = index + 1
val diffToAvg = ((score - avg) * 10).toInt() / 10.0
" 第${rank}名: $name - ${score} 分 (相对平均: ${diffToAvg} 分)"
}
// 简单评语
val comment = when {
avg >= 90 -> "整体水平非常优秀,保持当前学习节奏。"
avg >= 75 -> "整体水平良好,可以针对薄弱同学进行辅导。"
avg >= 60 -> "整体刚好及格,建议加强基础知识训练。"
else -> "整体水平偏低,需要系统性复习与训练。"
}
fun percent(part: Int): Double = if (count > 0) (part * 1000 / count) / 10.0 else 0.0
return "📊 成绩排行榜生成与分析\n" +
"━━━━━━━━━━━━━━━━━━━━━\n" +
"原始输入: $inputText\n\n" +
"1️⃣ 排行榜:\n" +
rankingLines.joinToString("\n") + "\n\n" +
"2️⃣ 基础统计:\n" +
" 人数: $count\n" +
" 最高分: $max\n" +
" 最低分: $min\n" +
" 平均分: ${((avg * 10).toInt() / 10.0)}\n\n" +
"3️⃣ 分数段统计:\n" +
" 优秀(>=90): $excellent 人 (${percent(excellent)}%)\n" +
" 良好(80-89): $good 人 (${percent(good)}%)\n" +
" 及格(60-79): $pass 人 (${percent(pass)}%)\n" +
" 不及格(<60): $fail 人 (${percent(fail)}%)\n\n" +
"4️⃣ 综合评语:\n" +
" $comment\n\n" +
"━━━━━━━━━━━━━━━━━━━━━\n" +
"✅ 分析完成!"
}
代码说明:
这是成绩排行榜生成与分析工具的核心 Kotlin 函数。函数接收一个包含"姓名 分数"对的字符串,用逗号分隔。首先验证输入不为空。使用 split(",") 按逗号分隔多个学生,再用空格分隔姓名和分数,使用 mapNotNull 过滤无效数据。按分数从高到低排序。计算基础统计:人数、最高分、最低分、平均分。按分数段统计:优秀(≥90)、良好(80-89)、及格(60-79)、不及格(<60)。使用 mapIndexed 生成排行榜文本,计算每个学生相对平均分的差值。根据平均分生成综合评语。定义 percent 函数计算百分比。最后将所有数据格式化为多部分输出字符串。
说明:
- 使用
split(",")切分多个同学,再用空格切分姓名与成绩 - 对解析失败的数据直接过滤掉,并在整体为空时返回错误提示
- 所有输出通过字符串拼接完成,方便 ArkTS 直接展示
JavaScript 编译输出与类型定义
执行构建脚本后,在 build/js/packages/hellokjs/kotlin/ 下生成:
hellokjs.mjs // ESModule 格式的 JS 模块
hellokjs.d.ts // TypeScript 类型定义
类型定义中会包含:
export declare function scoreRankingAnalyzer(inputText?: string): string;
代码说明:
这是 Kotlin 函数编译到 TypeScript 后生成的类型定义。声明了 scoreRankingAnalyzer 函数的签名:接收一个可选的字符串参数 inputText,返回字符串。这个类型定义允许 ArkTS/TypeScript 在导入 hellokjs 模块时获得完整的类型检查和智能代码提示,提高开发效率和代码安全性。
这样在 ArkTS/TypeScript 中导入 hellokjs 模块时可获得类型检查和智能提示。
ArkTS 页面集成与调用
首页 Index.ets 已改为“成绩排行榜生成与分析”页面,核心结构如下:
import { scoreRankingAnalyzer } from './hellokjs';
@Entry
@Component
struct Index {
@State message: string = '请输入姓名和分数组成的列表';
@State inputText: string = '张三 95, 李四 88, 王五 76';
@State resultText: string = '';
aboutToAppear(): void {
this.calculateRanking();
}
calculateRanking(): void {
try {
const input: string = this.inputText;
const result: string = scoreRankingAnalyzer(input);
this.resultText = result;
this.message = '✓ 计算完成';
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
this.message = `✗ 错误: ${errorMessage}`;
}
}
build() {
Column() {
// 标题、输入框、结果显示、默认示例&清空按钮等
}
}
}
代码说明:
这是 OpenHarmony ArkTS 页面的核心实现。首先导入 Kotlin 编译生成的 scoreRankingAnalyzer 函数。定义三个状态变量:message 显示操作状态,inputText 存储用户输入的学生成绩列表,resultText 存储分析结果。aboutToAppear() 生命周期钩子在页面加载时自动调用 calculateRanking() 进行初始计算。calculateRanking() 方法获取输入文本,调用 Kotlin 函数进行排行榜分析,更新结果和状态信息,使用 try-catch 捕获异常。build() 方法定义 UI 布局,包括标题、输入框、结果显示区域等。
说明:
- ArkTS 通过
inputText收集原始字符串,并直接传给 Kotlin 函数 - 返回的多行文本结果通过
resultText在 UI 中滚动展示
交互示例
示例 1:基础示例
输入:
张三 95, 李四 88, 王五 76
输出片段示例:
1️⃣ 排行榜:
第1名: 张三 - 95.0 分 (相对平均: 11.0 分)
第2名: 李四 - 88.0 分 (相对平均: 4.0 分)
第3名: 王五 - 76.0 分 (相对平均: -8.0 分)
2️⃣ 基础统计:
人数: 3
最高分: 95.0
最低分: 76.0
平均分: 84.0
3️⃣ 分数段统计:
优秀(>=90): 1 人 (...
更多推荐





所有评论(0)