android - 如何在 Kotlin 中按名称属性过滤对象列表中的对象列表
问题描述
我正在尝试完成一项被证明很困难的任务。如何实现在 Kotlin 中过滤列表的目标?我在这里用过滤器和地图寻找,但不可能做到。
我有这个数据类。
data class CategoryModel(
val collections: List<CollectionModel>,
val id: Int,
val name: String
)
data class CollectionModel(
val id: Int,
val image: String,
val name: String
)
我想做的是获取一个 CategoryModel 列表,其中只有与特定 collectionModel.name 的子字符串匹配的 collectionModel。
这是我尝试过的代码,但是如果 collectionModel 有两个元素,我都会得到两个元素,并且我只想要包含子字符串的元素:
collection.forEachIndexed { index, element ->
for (collectionModel in collection[index].collections) {
if (collectionModel.name.contains(textToSearch.capitalize())) {
collectionSearch.add(collection[index])
}
}
}
return collectionSearch
更新 1
collection.reduce{ acc, list -> list.collections.filter { it.name.contains(textToSearch.capitalize()) } }
给出这个错误:
解决方案
这感觉有点 hacky,因为下面的代码创建了CategoryModel
使用过滤列表的新对象CollectionModel
,但它似乎工作。它返回一个MutableList<CategoryModel>
因为
var collectionSearch: List<CategoryModel> = categoryModelList.filter {
// check each CategoryModel
categoryModel -> categoryModel.collections.filter {
// check if there are CollectionModels with a name containing capitalized textToSearch
collectionModel -> collectionModel.name.contains(textToSearch.capitalize())
}.isNotEmpty() // only consider those with a non empty result
}.toList() // get all the matching CategoryModels as List<CategoryModel>
fun main
像这样称呼它
fun main() {
// minimal data sample
var categoryModelList: List<CategoryModel> = listOf(
CategoryModel(listOf(CollectionModel(1, "collMod A", "nameA")), 1, "catMod A"),
CategoryModel(listOf(CollectionModel(1, "collMod B", "nameB")), 2, "catMod B")
);
// sample text to be found
val textToSearch: String = "b";
// here it is
var collectionSearch: List<CategoryModel> = categoryModelList.filter {
categoryModel -> categoryModel.collections.filter {
collectionModel -> collectionModel.name.contains(textToSearch.capitalize())
}.isNotEmpty()
}.toList()
println(collectionSearch)
}
产生以下输出:
[CategoryModel(collections=[CollectionModel(id=1, image=collMod B, name=nameB)], id=2, name=catMod B)]
这似乎是需要的。
编辑
明确需求后,下面的扩展功能List<CategoryModel>
可能就足够了,虽然感觉不完美:
fun List<CategoryModel>.getModified(condition: String): List<CategoryModel> {
var result: MutableList<CategoryModel> = mutableListOf();
this.forEach { categoryModel ->
// get a list of matching CollectionModels
val cols = categoryModel.collections.filter { collectionModel ->
collectionModel.name.contains(condition.capitalize())
}
// if the list is not empty
if (cols.isNotEmpty()) {
/*
* add a new item to the result using the filtered collections
* and the other (unmodified) attributes
*/
result.add(CategoryModel(cols, categoryModel.id, categoryModel.name))
}
}
return result
}
当我这样称呼它时
fun main() {
// minimal data sample
var categoryModelList: List<CategoryModel> = listOf(
CategoryModel(mutableListOf(CollectionModel(1, "collMod A", "nameA"),
CollectionModel(2, "collMod B", "nameB")
), 1, "catMod 1"),
CategoryModel(mutableListOf(CollectionModel(3, "collMod B", "nameB")), 2, "catMod 2"),
CategoryModel(mutableListOf(CollectionModel(4, "collMod BB", "nameBB"),
CollectionModel(5, "collMod C", "nameC")
), 3, "catMod 3"),
CategoryModel(mutableListOf(CollectionModel(6, "collMod A", "nameA"),
CollectionModel(7, "collMod D", "nameD")
), 4, "catMod 4")
);
// sample text to be found
val textToSearch: String = "b";
// print the source
println(categoryModelList)
// and the modified list in order to compare them
println(categoryModelList.getModified(textToSearch))
}
输出似乎是所需的:
[CategoryModel(collections=[CollectionModel(id=1, image=collMod A, name=nameA), CollectionModel(id=2, image=collMod B, name=nameB)], id=1, name=catMod 1), CategoryModel(collections=[CollectionModel(id=3, image=collMod B, name=nameB)], id=2, name=catMod 2), CategoryModel(collections=[CollectionModel(id=4, image=collMod BB, name=nameBB), CollectionModel(id=5, image=collMod C, name=nameC)], id=2, name=catMod 3), CategoryModel(collections=[CollectionModel(id=6, image=collMod A, name=nameA), CollectionModel(id=7, image=collMod D, name=nameD)], id=3, name=catMod 4)]
[CategoryModel(collections=[CollectionModel(id=2, image=collMod B, name=nameB)], id=1, name=catMod 1), CategoryModel(collections=[CollectionModel(id=3, image=collMod B, name=nameB)], id=2, name=catMod 2), CategoryModel(collections=[CollectionModel(id=4, image=collMod BB, name=nameBB)], id=2, name=catMod 3)]
这意味着只剩CategoryModel
下匹配CollectionModel
s 的 scollections
并且只剩下那些,所有其他的都已被删除。
推荐阅读
- bash - shell 函数是否导出到子进程?
- r - 如何将 Global Environment 的所有数据框与 R 中的字符合并?
- python - 为什么 AlexNet 在卷积层使用 96、256 和 384 个过滤器?
- database - 如何解析 ndjson 文件?
- javascript - 如何在不使用 xpath 的情况下使用文档查询选择器获取文本?
- rich-text-editor - 有没有办法在 Rails 6 中禁用动作文本的图像/附件部分?
- sql - SQL在null时消除行
- rust - 为什么这个 Rust 代码需要生命周期参数
- javascript - 正则表达式匹配行尾,除非它以右括号结尾
- java - 每 X 秒运行一次 java 代码,但如果代码有效,请不要等待 TimeUnit.sleep