在另一个列表Kotlin的每个函数中过滤一个列表



我正在尝试过滤一个列表,并将其返回到另一个列表的映射函数中。

val userChoiceCategories = recommendedCategoryDb.find(RecommendedCategory::userId eq userId).toList()

userChoiceCategories.forEach {
//
return articleDb.find().toList()
.filter { article ->
article.category != it.category.name
}
}
return listOf()

我想显示除一个用户选择的以外的所有其他类别的文章以在"浏览"页面中显示它们。forEach循环只适用于列表中的第一项,我想它会停止。有没有澄清我哪里错了?

Kotlin有一个称为限定返回的概念,这意味着lambdas中的返回语句(如传递给forEach的返回语句(需要以不同的方式处理。

请考虑以下示例

这将只打印名字,然后退出(就像你的方法一样(并返回1个

fun printNames(names: List<String>): Int {
names.forEach {
println(it)
return 1
}
return names.size
}

这将打印所有名称并返回列表大小,但内部返回毫无意义的

fun printNames(names: List<String>): Int {
names.forEach {
println(it)
return@forEach
}
return names.size
}

这也将打印的所有名称

fun printNames(names: List<String>): Int {
names.forEach {
println(it)
}
return names.size
}

这将只打印非空名称,这里的return@forEach就像普通for循环中的continue

fun printNames(names: List<String>): Int {
names.forEach {
if( it.isEmpty() ) return@forEach
println(it)
}
return names.size
}

那么这对您的问题有何影响

我看到你有两个问题:

  1. 立即退出循环的未限定返回(如您在问题中所述(
  2. 事实上,它没有累积应用过滤器(过滤器返回过滤列表(

我还不完全清楚你想做什么,但你发布的代码的固定版本会是这样的(似乎试图返回与用户选择类别不匹配的文章列表(

var result = articleDb.find().toList()
userChoiceCategories.forEach { choice ->
//
result = result.filter { article ->
article.category != choice.category.name
}
}
return result

作为一种更紧凑的方法,如果你想返回类别与任何选定类别匹配的文章,你可以这样做(如果你想要不匹配类别列表的文章,可以反转布尔逻辑或使用filterNot(

// find all articles whose category is in the user choice list
return articleDb.find().toList().filter { article ->
userChoiceCategories.any { choice ->
article.category == choice.category.name
}
}
val userChoiceCategories = recommendedCategoryDb.find(RecommendedCategory::userId eq userId).toList()
val categoriesToOmit = userChoiceCategories.map { it.category.name }.toSet()
return articleDb.find().toList().filter { !categoriesToOmit.contains(it.category) }

以及更简洁的形式:

return recommendedCategoryDb
.find(RecommendedCategory::userId eq userId).toList()
.map { it.category.name }.toSet()
.let { toOmit ->
articleDb
.find().toList()
.filter { article -> article.category !in toOmit } 
}

最新更新