数据过滤库 - 基于KMP OpenHarmony的跨平台方案

项目概述
数据过滤是现代应用开发中的重要功能。无论是在列表筛选、搜索结果过滤、数据清洗还是条件查询中,都需要进行数据的过滤和处理。然而,不同的编程语言和平台对数据过滤的实现方式各不相同,这导致开发者需要在不同平台上重复编写类似的逻辑。
本文介绍一个基于 Kotlin Multiplatform (KMP) 和 OpenHarmony 平台的数据过滤库示例。这个库提供了一套完整的数据过滤能力,包括条件过滤、范围过滤、模式匹配等功能。通过 KMP 技术,我们可以在 Kotlin 中编写一次代码,然后编译到 JavaScript 和其他目标平台,最后在 OpenHarmony 的 ArkTS 中调用这些功能。
技术架构
多平台支持
- Kotlin/JVM: 后端服务和桌面应用
- Kotlin/JS: Web 应用和浏览器环境
- OpenHarmony/ArkTS: 鸿蒙操作系统应用
核心功能模块
- 条件过滤: 按自定义条件过滤数据
- 范围过滤: 按数值范围过滤数据
- 模式匹配: 按模式进行过滤
- 多条件过滤: 按多个条件进行过滤
- 反向过滤: 获取不符合条件的数据
- 过滤统计: 统计过滤结果
- 过滤排序: 对过滤结果排序
- 过滤性能: 监控过滤性能
Kotlin 实现
核心过滤类
// 文件: src/commonMain/kotlin/DataFilter.kt
/**
* 数据过滤工具类
* 提供各种数据过滤功能
*/
class DataFilter {
data class FilterResult(
val originalData: List<Int>,
val filteredData: List<Int>,
val originalSize: Int,
val filteredSize: Int,
val filterRatio: Double,
val filterTime: Long
)
data class FilterConfig(
val enableStatistics: Boolean = true,
val enableLogging: Boolean = false,
val caseSensitive: Boolean = true
)
private var config = FilterConfig()
/**
* 设置过滤配置
* @param config 配置对象
*/
fun setConfig(config: FilterConfig) {
this.config = config
}
/**
* 条件过滤
* @param data 数据列表
* @param predicate 过滤条件
* @return 过滤结果
*/
fun filterByCondition(data: List<Int>, predicate: (Int) -> Boolean): FilterResult {
val startTime = System.currentTimeMillis()
val originalSize = data.size
val filteredData = data.filter(predicate)
val filterTime = System.currentTimeMillis() - startTime
val filterRatio = (filteredData.size.toDouble() / originalSize) * 100
return FilterResult(
data,
filteredData,
originalSize,
filteredData.size,
filterRatio,
filterTime
)
}
/**
* 范围过滤
* @param data 数据列表
* @param min 最小值
* @param max 最大值
* @return 过滤结果
*/
fun filterByRange(data: List<Int>, min: Int, max: Int): FilterResult {
return filterByCondition(data) { it in min..max }
}
/**
* 大于过滤
* @param data 数据列表
* @param threshold 阈值
* @return 过滤结果
*/
fun filterGreaterThan(data: List<Int>, threshold: Int): FilterResult {
return filterByCondition(data) { it > threshold }
}
/**
* 小于过滤
* @param data 数据列表
* @param threshold 阈值
* @return 过滤结果
*/
fun filterLessThan(data: List<Int>, threshold: Int): FilterResult {
return filterByCondition(data) { it < threshold }
}
/**
* 偶数过滤
* @param data 数据列表
* @return 过滤结果
*/
fun filterEven(data: List<Int>): FilterResult {
return filterByCondition(data) { it % 2 == 0 }
}
/**
* 奇数过滤
* @param data 数据列表
* @return 过滤结果
*/
fun filterOdd(data: List<Int>): FilterResult {
return filterByCondition(data) { it % 2 != 0 }
}
/**
* 反向过滤
* @param data 数据列表
* @param predicate 过滤条件
* @return 过滤结果
*/
fun filterNot(data: List<Int>, predicate: (Int) -> Boolean): FilterResult {
return filterByCondition(data) { !predicate(it) }
}
/**
* 多条件过滤
* @param data 数据列表
* @param predicates 过滤条件列表
* @return 过滤结果
*/
fun filterByMultipleConditions(data: List<Int>, predicates: List<(Int) -> Boolean>): FilterResult {
val startTime = System.currentTimeMillis()
val originalSize = data.size
val filteredData = data.filter { item ->
predicates.all { predicate -> predicate(item) }
}
val filterTime = System.currentTimeMillis() - startTime
val filterRatio = (filteredData.size.toDouble() / originalSize) * 100
return FilterResult(
data,
filteredData,
originalSize,
filteredData.size,
filterRatio,
filterTime
)
}
/**
* 获取过滤统计信息
* @param result 过滤结果
* @return 统计信息
*/
fun getFilterStatistics(result: FilterResult): Map<String, Any> {
return mapOf(
"originalSize" to result.originalSize,
"filteredSize" to result.filteredSize,
"removedCount" to (result.originalSize - result.filteredSize),
"filterRatio" to String.format("%.2f", result.filterRatio),
"filterTime" to "${result.filterTime}ms",
"efficiency" to if (result.filterTime > 0) String.format("%.2f", result.originalSize.toDouble() / result.filterTime) else "N/A"
)
}
/**
* 生成过滤报告
* @param result 过滤结果
* @return 报告字符串
*/
fun generateFilterReport(result: FilterResult): String {
val stats = getFilterStatistics(result)
val report = StringBuilder()
report.append("数据过滤报告\n")
report.append("=".repeat(40)).append("\n")
report.append("原始数据量: ${stats["originalSize"]}\n")
report.append("过滤后数据量: ${stats["filteredSize"]}\n")
report.append("移除数据量: ${stats["removedCount"]}\n")
report.append("过滤比例: ${stats["filterRatio"]}%\n")
report.append("过滤耗时: ${stats["filterTime"]}\n")
report.append("处理效率: ${stats["efficiency"]} 项/ms\n")
return report.toString()
}
}
Kotlin 实现的核心特点
Kotlin 实现中的过滤功能充分利用了 Kotlin 标准库的集合处理能力。条件过滤使用了 filter 方法。范围过滤使用了 in 操作符。
多条件过滤使用了 all 方法。反向过滤使用了 not 操作符。统计信息使用了 Map 数据结构。
JavaScript 实现
编译后的 JavaScript 代码
// 文件: build/js/packages/kmp_openharmony-js/kotlin/kmp_openharmony.js
// (由 Kotlin 编译器自动生成)
/**
* DataFilter 类的 JavaScript 版本
* 通过 Kotlin/JS 编译器从 Kotlin 源代码生成
*/
class DataFilter {
constructor() {
this.config = {
enableStatistics: true,
enableLogging: false,
caseSensitive: true
};
}
/**
* 设置过滤配置
* @param {Object} config - 配置对象
*/
setConfig(config) {
this.config = { ...this.config, ...config };
}
/**
* 条件过滤
* @param {Array} data - 数据列表
* @param {Function} predicate - 过滤条件
* @returns {Object} 过滤结果
*/
filterByCondition(data, predicate) {
const startTime = Date.now();
const originalSize = data.length;
const filteredData = data.filter(predicate);
const filterTime = Date.now() - startTime;
const filterRatio = (filteredData.length / originalSize) * 100;
return {
originalData: data,
filteredData: filteredData,
originalSize: originalSize,
filteredSize: filteredData.length,
filterRatio: filterRatio,
filterTime: filterTime
};
}
/**
* 范围过滤
* @param {Array} data - 数据列表
* @param {number} min - 最小值
* @param {number} max - 最大值
* @returns {Object} 过滤结果
*/
filterByRange(data, min, max) {
return this.filterByCondition(data, item => item >= min && item <= max);
}
/**
* 大于过滤
* @param {Array} data - 数据列表
* @param {number} threshold - 阈值
* @returns {Object} 过滤结果
*/
filterGreaterThan(data, threshold) {
return this.filterByCondition(data, item => item > threshold);
}
/**
* 小于过滤
* @param {Array} data - 数据列表
* @param {number} threshold - 阈值
* @returns {Object} 过滤结果
*/
filterLessThan(data, threshold) {
return this.filterByCondition(data, item => item < threshold);
}
/**
* 偶数过滤
* @param {Array} data - 数据列表
* @returns {Object} 过滤结果
*/
filterEven(data) {
return this.filterByCondition(data, item => item % 2 === 0);
}
/**
* 奇数过滤
* @param {Array} data - 数据列表
* @returns {Object} 过滤结果
*/
filterOdd(data) {
return this.filterByCondition(data, item => item % 2 !== 0);
}
/**
* 反向过滤
* @param {Array} data - 数据列表
* @param {Function} predicate - 过滤条件
* @returns {Object} 过滤结果
*/
filterNot(data, predicate) {
return this.filterByCondition(data, item => !predicate(item));
}
/**
* 获取过滤统计信息
* @param {Object} result - 过滤结果
* @returns {Object} 统计信息
*/
getFilterStatistics(result) {
return {
originalSize: result.originalSize,
filteredSize: result.filteredSize,
removedCount: result.originalSize - result.filteredSize,
filterRatio: result.filterRatio.toFixed(2),
filterTime: `${result.filterTime}ms`,
efficiency: result.filterTime > 0 ? (result.originalSize / result.filterTime).toFixed(2) : 'N/A'
};
}
}
JavaScript 实现的特点
JavaScript 版本完全由 Kotlin/JS 编译器自动生成,确保了与 Kotlin 版本的行为完全一致。JavaScript 的 filter 方法提供了过滤能力。
filter 方法用于条件过滤。Date.now() 用于时间测量。箭头函数用于条件定义。
ArkTS 调用代码
OpenHarmony 应用集成
// 文件: kmp_ceshiapp/entry/src/main/ets/pages/DataFilterPage.ets
import { DataFilter } from '../../../../../../../build/js/packages/kmp_openharmony-js/kotlin/kmp_openharmony';
@Entry
@Component
struct DataFilterPage {
@State selectedFilter: string = 'range';
@State inputData: string = '';
@State result: string = '';
@State resultTitle: string = '';
private dataFilter = new DataFilter();
private filters = [
{ name: '📊 范围过滤', value: 'range' },
{ name: '⬆️ 大于过滤', value: 'greater' },
{ name: '⬇️ 小于过滤', value: 'less' },
{ name: '🔢 偶数过滤', value: 'even' },
{ name: '🔤 奇数过滤', value: 'odd' },
{ name: '📈 统计', value: 'stats' },
{ name: '📋 报告', value: 'report' },
{ name: '🔄 演示', value: 'demo' }
];
build() {
Column() {
// 标题
Text('🔍 数据过滤库示例')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
.width('100%')
.padding(20)
.backgroundColor('#1A237E')
.textAlign(TextAlign.Center)
Scroll() {
Column() {
// 过滤方式选择
Column() {
Text('选择过滤方式')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.fontColor('#333333')
.margin({ bottom: 12 })
Flex({ wrap: FlexWrap.Wrap }) {
ForEach(this.filters, (filter: { name: string; value: string }) => {
Button(filter.name)
.layoutWeight(1)
.height(40)
.margin({ right: 8, bottom: 8 })
.backgroundColor(this.selectedFilter === filter.value ? '#1A237E' : '#E0E0E0')
.fontColor(this.selectedFilter === filter.value ? '#FFFFFF' : '#333333')
.fontSize(11)
.onClick(() => {
this.selectedFilter = filter.value;
this.result = '';
this.resultTitle = '';
})
})
}
.width('100%')
}
.width('95%')
.margin({ top: 16, left: '2.5%', right: '2.5%', bottom: 16 })
.padding(12)
.backgroundColor('#FFFFFF')
.borderRadius(6)
// 数据输入
Column() {
Text('输入数据(用逗号分隔)')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.fontColor('#333333')
.margin({ bottom: 8 })
TextInput({ placeholder: '例如:1,2,3,4,5,6,7,8,9,10', text: this.inputData })
.onChange((value) => this.inputData = value)
.width('100%')
.height(50)
.padding(12)
.border({ width: 1, color: '#4DB6AC' })
.borderRadius(6)
.fontSize(12)
}
.width('95%')
.margin({ left: '2.5%', right: '2.5%', bottom: 16 })
.padding(12)
.backgroundColor('#FFFFFF')
.borderRadius(6)
// 操作按钮
Row() {
Button('✨ 过滤')
.layoutWeight(1)
.height(44)
.backgroundColor('#1A237E')
.fontColor('#FFFFFF')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.borderRadius(6)
.onClick(() => this.executeFilter())
Blank()
.width(12)
Button('🔄 清空')
.layoutWeight(1)
.height(44)
.backgroundColor('#F5F5F5')
.fontColor('#1A237E')
.fontSize(14)
.border({ width: 1, color: '#4DB6AC' })
.borderRadius(6)
.onClick(() => {
this.inputData = '';
this.result = '';
this.resultTitle = '';
})
}
.width('95%')
.margin({ left: '2.5%', right: '2.5%', bottom: 16 })
// 结果显示
if (this.resultTitle) {
Column() {
Text(this.resultTitle)
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
.width('100%')
.padding(12)
.backgroundColor('#1A237E')
.borderRadius(6)
.textAlign(TextAlign.Center)
.margin({ bottom: 12 })
Scroll() {
Text(this.result)
.fontSize(12)
.fontColor('#333333')
.fontFamily('monospace')
.textAlign(TextAlign.Start)
.width('100%')
.padding(12)
.selectable(true)
}
.width('100%')
.height(300)
.backgroundColor('#F9F9F9')
.border({ width: 1, color: '#4DB6AC' })
.borderRadius(6)
}
.width('95%')
.margin({ left: '2.5%', right: '2.5%', bottom: 16 })
.padding(12)
.backgroundColor('#FFFFFF')
.borderRadius(6)
}
}
.width('100%')
}
.layoutWeight(1)
.width('100%')
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
private executeFilter() {
const inputStr = this.inputData || '1,2,3,4,5,6,7,8,9,10';
const data = inputStr.split(',').map(s => parseInt(s.trim(), 10)).filter(n => !isNaN(n));
if (data.length === 0) {
this.resultTitle = '❌ 错误';
this.result = '请输入有效的数据';
return;
}
try {
switch (this.selectedFilter) {
case 'range':
const rangeResult = this.dataFilter.filterByRange(data, 3, 7);
this.resultTitle = '📊 范围过滤 (3-7)';
this.result = `原始: ${rangeResult.originalData}\n过滤后: ${rangeResult.filteredData}\n原始数量: ${rangeResult.originalSize}\n过滤后数量: ${rangeResult.filteredSize}\n过滤比例: ${rangeResult.filterRatio.toFixed(2)}%`;
break;
case 'greater':
const greaterResult = this.dataFilter.filterGreaterThan(data, 5);
this.resultTitle = '⬆️ 大于过滤 (>5)';
this.result = `原始: ${greaterResult.originalData}\n过滤后: ${greaterResult.filteredData}\n过滤数量: ${greaterResult.filteredSize}`;
break;
case 'less':
const lessResult = this.dataFilter.filterLessThan(data, 5);
this.resultTitle = '⬇️ 小于过滤 (<5)';
this.result = `原始: ${lessResult.originalData}\n过滤后: ${lessResult.filteredData}\n过滤数量: ${lessResult.filteredSize}`;
break;
case 'even':
const evenResult = this.dataFilter.filterEven(data);
this.resultTitle = '🔢 偶数过滤';
this.result = `原始: ${evenResult.originalData}\n过滤后: ${evenResult.filteredData}\n偶数数量: ${evenResult.filteredSize}`;
break;
case 'odd':
const oddResult = this.dataFilter.filterOdd(data);
this.resultTitle = '🔤 奇数过滤';
this.result = `原始: ${oddResult.originalData}\n过滤后: ${oddResult.filteredData}\n奇数数量: ${oddResult.filteredSize}`;
break;
case 'stats':
const statsResult = this.dataFilter.filterByRange(data, 3, 7);
const stats = this.dataFilter.getFilterStatistics(statsResult);
this.resultTitle = '📈 过滤统计';
this.result = `原始数量: ${stats.originalSize}\n过滤后数量: ${stats.filteredSize}\n移除数量: ${stats.removedCount}\n过滤比例: ${stats.filterRatio}%\n耗时: ${stats.filterTime}`;
break;
case 'report':
const reportResult = this.dataFilter.filterByRange(data, 3, 7);
const report = this.dataFilter.generateFilterReport(reportResult);
this.resultTitle = '📋 过滤报告';
this.result = report;
break;
case 'demo':
const demoData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const demoResult = this.dataFilter.filterByRange(demoData, 4, 8);
this.resultTitle = '🔄 演示数据';
this.result = `演示数据: ${demoResult.originalData}\n过滤结果: ${demoResult.filteredData}\n过滤效果: 从 ${demoResult.originalSize} 个数据中过滤出 ${demoResult.filteredSize} 个`;
break;
}
} catch (e) {
this.resultTitle = '❌ 过滤出错';
this.result = `错误: ${e}`;
}
}
}
ArkTS 集成的关键要点
在 OpenHarmony 应用中集成过滤工具库需要考虑多种过滤方式和用户体验。我们设计了一个灵活的 UI,能够支持不同的过滤操作。
过滤方式选择界面使用了 Flex 布局和 FlexWrap 来实现响应式的按钮排列。数据输入使用了 TextInput 组件。
结果显示使用了可选择的文本,这样用户可以轻松复制过滤结果。对于不同的过滤方式,我们显示了相应的过滤处理结果。
工作流程详解
数据过滤的完整流程
- 过滤方式选择: 用户在 ArkTS UI 中选择要使用的过滤方式
- 数据输入: 用户输入要过滤的数据
- 处理执行: 调用 DataFilter 的相应方法
- 结果展示: 将过滤结果显示在 UI 中
跨平台一致性
通过 KMP 技术,我们确保了在所有平台上的行为一致性。无论是在 Kotlin/JVM、Kotlin/JS 还是通过 ArkTS 调用,数据过滤的逻辑和结果都是完全相同的。
实际应用场景
列表筛选
在展示列表时,需要进行数据过滤以显示符合条件的项目。这个工具库提供了完整的列表过滤功能。
搜索结果过滤
在搜索功能中,需要过滤搜索结果。这个工具库提供了搜索结果过滤能力。
数据清洗
在处理数据时,需要过滤无效或不符合要求的数据。这个工具库提供了数据清洗过滤功能。
条件查询
在进行条件查询时,需要过滤符合条件的数据。这个工具库提供了条件查询过滤能力。
性能优化
过滤算法优化
在处理大量数据时,应该选择高效的过滤算法以提高性能。
缓存过滤结果
在频繁进行相同过滤时,可以缓存过滤结果以避免重复过滤。
安全性考虑
数据验证
在进行数据过滤时,应该进行验证以确保数据的有效性。
过滤验证
在过滤完成后,应该进行验证以确保过滤的正确性。
总结
这个 KMP OpenHarmony 数据过滤库示例展示了如何使用现代的跨平台技术来处理常见的数据过滤任务。通过 Kotlin Multiplatform 技术,我们可以在一个地方编写业务逻辑,然后在多个平台上使用。
数据过滤是应用开发中的重要功能。通过使用这样的工具库,开发者可以快速、可靠地实现各种过滤操作,从而提高应用的数据处理能力。
在实际应用中,建议根据具体的需求进行定制和扩展,例如添加更多的过滤策略、实现更复杂的过滤规则等高级特性。同时,定期进行性能测试和优化,确保应用的过滤系统保持高效运行。欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)