有没有办法将过滤器合并并映射到Kotlin中的单个操作中



以下代码将寻找"=",然后将它们分开。如果没有"=",请首先过滤它们

myPairStr.asSequence()
        .filter { it.contains("=") }
        .map { it.split("=") }

但是看到我们有两个

        .filter { it.contains("=") }
        .map { it.split("=") }

想知道是否有一个操作可以结合操作而不是单独进行操作?

您可以使用mapNotNull而不是map

myPairStr.asSequence().mapNotNull { it.split("=").takeIf { it.size >= 2 } }

如果split方法返回的list的大小为 1 ,即如果字符串中不存在=,则takeIf功能将返回nullmapNotNull将仅采用non null值并将其放在列表中(最终返回(。就您而言,此解决方案将起作用。在其他情况下,实现(合并filter& map(可能不同。

我看到了您的观点,在引擎盖split下方也在执行indexOf-检查以获取适当的零件。

我不知道有任何这样的功能支持单个操作中的两个操作,即使这种功能基本上只是类似于我们对private fun split的实现。

因此,如果您真的想要一步(并且需要更频繁地需要该功能(,则可能需要实现自己的splitOrNull函数,基本上复制当前(私有(split-实施术,并主要适应其中的3个部分(返回类型List<String>?,如果indexOf提供-1,则只需返回null;和一些默认值即可使其易于使用(ignoreCase=falselimit=0(;用// added// changed标记了更改(:

(: (
fun CharSequence.splitOrNull(delimiter: String, ignoreCase: Boolean = false, limit: Int = 0): List<String>? { // changed
    require(limit >= 0, { "Limit must be non-negative, but was $limit." })
    var currentOffset = 0
    var nextIndex = indexOf(delimiter, currentOffset, ignoreCase)
    if (nextIndex == -1 || limit == 1) {
        if (currentOffset == 0 && nextIndex == -1) // added
            return null                            // added
        return listOf(this.toString())
    }
    val isLimited = limit > 0
    val result = ArrayList<String>(if (isLimited) limit.coerceAtMost(10) else 10)
    do {
        result.add(substring(currentOffset, nextIndex))
        currentOffset = nextIndex + delimiter.length
        // Do not search for next occurrence if we're reaching limit
        if (isLimited && result.size == limit - 1) break
        nextIndex = indexOf(delimiter, currentOffset, ignoreCase)
    } while (nextIndex != -1)
    result.add(substring(currentOffset, length))
    return result
}

拥有这样的函数,您可以将contains/indexOfsplit的同时总结到一个呼叫中:

myPairStr.asSequence()
         .mapNotNull {
           it.splitOrNull("=") // or: it.splitOrNull("=", limit = 2)
         }

否则您当前的方法已经足够好了。它的一种变体就是在分开后检查分裂的大小(基本上是删除编写contains('=')并仅检查预期尺寸的需求,例如:

myPairStr.asSequence()
         .map { it.split('=') } 
         .filter { it.size > 1 }

如果要拆分$key=$value -Formats,value实际上可能包含其他=,则可能需要使用以下内容:

myPairStr.asSequence()
         .map { it.split('=', limit = 2) } 
         .filter { it.size > 1 }
//       .associate { (key, value) -> key to value }

相关内容

最新更新