scala 缩短MQTT主题过滤函数

qkf9rpyu  于 2023-01-30  发布在  Scala
关注(0)|答案(1)|浏览(170)

我写了下面的逻辑函数,但是我确信可以把它写得更短一些。如果你不熟悉MQTT通配符,you can read up on them here.
self是我们“订阅”的主题,包含零个或多个通配符。incoming是我们接收到内容的主题,必须完全匹配self主题,或者符合通配符规则。
我对这个函数的所有测试都成功了,但我就是不喜欢这个Scala函数的冗长和“不灵活”。

def filterTopic(incoming: String, self: String): Boolean = {
  if (incoming == self || self == "#") {
    true
  } else if (self.startsWith("#") || (self.contains("#") && !self.endsWith("#")) || self.endsWith("+")) {
    false
  } else {
    var valid = true
    val selfSplit = self.split('/')
    var j = 0

    for (i <- selfSplit.indices) {
      if (selfSplit(i) != "+" && selfSplit(i) != "#" && selfSplit(i) != incoming.split('/')(i)) {
        valid = false
      }
      j += 1
    }

    if (j < selfSplit.length && selfSplit(j) == "#") {
      j += 1
    }

    j == selfSplit.length && valid
  }
}
jtw3ybtb

jtw3ybtb1#

这里有一个尝试,假设'+'可以在末尾,主题结构良好

def filterTopic(incoming: String, self: String): Boolean = {
        // helper function that works on lists of parts of the topics
        def go(incParts: List[String], sParts: List[String]): Boolean = (incParts, sParts) match {
            // if they're the same list, the topics match
            case (is, ss) if is == ss => true
            // if sParts is just a single "#", the topics match
            case (_, "#" :: Nil) => true
            // if sParts starts with '+', just check if the rest match
            case (_ :: is, s :: ss) if s == "+" =>
                go(is, ss)
            // otherwise the first parts have to match, and we check the rest
            case (i :: is, s :: ss) if i == s =>
                go(is, ss)
            // otherwise they don't match
            case _ => false
        }

        // split the topic strings into parts 
        go(incoming.split('/').toList, self.split('/').toList)
    }

相关问题