在另一个列表的 forEach 函数中过滤一个列表 - Kotlin
Filter a list inside forEach function of another list - Kotlin
我正在尝试过滤一个列表 return 它在另一个列表的映射函数中。
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 有一个叫做 qualified returns, which means return statements inside lambdas (like the one passed to forEach
) 的概念需要以不同的方式处理。
考虑以下示例。
这将只打印名字,然后退出(就像你的方法一样)和 return 1
fun printNames(names: List<String>): Int {
names.forEach {
println(it)
return 1
}
return names.size
}
这将打印所有名称和 return 列表大小,但内部 return 毫无意义
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
}
那么这对您的问题有何影响?
我看到你的东西有两个问题:
- 立即退出循环的不合格return(如您在问题中所述)
- 事实是它没有累积应用过滤器(filter return过滤列表)
我还不完全清楚你还在尝试做什么,但是你发布的代码的固定版本看起来像这样(似乎是在尝试 return 做的文章列表与用户选择的类别不匹配)
var result = articleDb.find().toList()
userChoiceCategories.forEach { choice ->
//
result = result.filter { article ->
article.category != choice.category.name
}
}
return result
作为一种更紧凑的方式,如果您想 return 其类别与任何选定类别匹配的文章,您可以这样做(并且可以反转布尔逻辑或使用 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 }
}
我正在尝试过滤一个列表 return 它在另一个列表的映射函数中。
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 有一个叫做 qualified returns, which means return statements inside lambdas (like the one passed to forEach
) 的概念需要以不同的方式处理。
考虑以下示例。
这将只打印名字,然后退出(就像你的方法一样)和 return 1
fun printNames(names: List<String>): Int {
names.forEach {
println(it)
return 1
}
return names.size
}
这将打印所有名称和 return 列表大小,但内部 return 毫无意义
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
}
那么这对您的问题有何影响?
我看到你的东西有两个问题:
- 立即退出循环的不合格return(如您在问题中所述)
- 事实是它没有累积应用过滤器(filter return过滤列表)
我还不完全清楚你还在尝试做什么,但是你发布的代码的固定版本看起来像这样(似乎是在尝试 return 做的文章列表与用户选择的类别不匹配)
var result = articleDb.find().toList()
userChoiceCategories.forEach { choice ->
//
result = result.filter { article ->
article.category != choice.category.name
}
}
return result
作为一种更紧凑的方式,如果您想 return 其类别与任何选定类别匹配的文章,您可以这样做(并且可以反转布尔逻辑或使用 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 }
}