问题描述
科特琳经常使用非常务实的方法.我想知道是否有一些我不知道的事情来简化只要求一些已知值的过滤谓词.
Kotlin often uses very pragmatic approaches. I wonder whether there is some I don't know of to simplify a filter predicate which just asks for some known values.
例如考虑以下列表:
val list = listOf("one", "two", "2", "three")
要过滤掉"two"
和"2"
,可以通过多种方式来实现过滤,例如:
To filter out "two"
and "2"
filtering can be accomplished in several ways, e.g.:
list.filter {
it in listOf("two", "2") // but that creates a new list every time... (didn't check though)
}
// extracting the list first, uses more code... and may hide the list somewhere sooner or later
val toCheck = listOf("two", "2")
list.filter { it in toCheck }
// similar, but probably less readable due to naming ;-)
list.filter(toCheck::contains)
// alternative using when, but that's not easier for this specific case and definitely longer:
list.filter {
when (it) {
"two", "2" -> true
else -> false
}
}
// probably one of the simplest... but not so nice, if we need to check more then 2 values
list.filter { it == "two" || it == "2" }
我想知道...是否有类似list.filter { it in ("two", "2") }
的东西或任何其他简单的方法来为已知值/常量创建/使用简短谓词?最后,我只想检查一下.
I wonder... is there something like list.filter { it in ("two", "2") }
or any other simple way to create/use a short predicate for known values/constants? In the end that's all I wanted to check.
我只是意识到该示例没有多大意义,因为listOf("anything", "some", "other").filter { it in listOf("anything") }
将始终是:listOf("anything")
.但是,列表交集在处理例如Map
.在过滤器实际上不只返回过滤后的值的地方(例如.filterKeys
).但是,减法(即list.filterNot { it in listOf("two", "2") }
)在列表中也很有意义.
I just realised that the sample doesn't make much sense as listOf("anything", "some", "other").filter { it in listOf("anything") }
will always be just: listOf("anything")
. However, the list intersection makes sense in constellations where dealing with, e.g. a Map
. In places where the filter actually doesn't return only the filtered value (e.g. .filterKeys
). The subtraction (i.e. list.filterNot { it in listOf("two", "2") }
) however also makes sense in lists as well.
推荐答案
Kotlin对集合中的集合操作提供了一些
Kotlin provides some set operations on collections which are
-
intersect
(两个集合的共同点) -
union
(将两个集合合并) -
subtract
(没有其他元素的集合)
intersect
(what both collections have in common)union
(combine both collections)subtract
(collections without elements of the other)
根据您的情况,可以使用设置操作subtract
In your case, instead of filter, you may use the set operation subtract
val filteredList = list.subtract(setOf("two","2"))
然后您就可以了.
和 fun (意为双关语)并没有到此为止:您可以使用自己的功能扩展集合,例如缺少的outerJoin
或用于过滤without
或运算符,例如/
表示intersect
and the fun (pun intended) doesn't end there: you could extend the collections with your own functions such as a missing outerJoin
or for filtering something like without
or operators i.e. /
for intersect
例如,通过添加这些
infix fun <T> Iterable<T>.without(other Iterable<T>) = this.subtract(other)
infix fun <T> Iterable<T>.excluding(other Iterable<T>) = this.subtract(other)
operator fun <T> Iterable<T>.div(other: Iterable<T>) = this.intersect(other)
您的代码-当使用相交应用于您的示例时-将变成
Your code - when applied to your example using the intersect - would become
val filtered = list / filter //instead of intersect filter
或-而不是减去:
val filtered = list without setOf("two", "2")
或
val filtered = list excluding setOf("two", "2")
足够实用吗?
这篇关于检查多个已知值时简化谓词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!