【问题标题】:View vs LazyList查看与懒惰列表
【发布时间】:2022-01-11 05:01:25
【问题描述】:
val patterns = Seq(
  "the name and age are ([a-z]+), ([0-9]+)".r,
  "name:([a-z]+),age:([0-9]+)".r,
  "n=([a-z]+),a=([0-9]+)".r
)
def transform(subject: String): Option[String] = {
  patterns.map(_.unapplySeq(subject)).collectFirst { case Some(List(name, age)) => s"$name$age" }
}
println(transform("name:joe,age:42")) // Some(joe42)

这个在正则表达式列表中查找和转换第一个匹配项的代码可以通过提前返回平均情况来改进

考虑到性能和线程安全,使patterns 成为惰性集合的最佳方法是什么?视图可以被多个线程重用,还是应该为每次调用transform 创建一个新视图?

  1. patterns.view
  2. patterns.to(LazyList)

【问题讨论】:

  • 为什么不使用单一的正则表达式模式?然后懒惰是内置的。
  • 确实如此,但提取匹配变得更加困难:Some(List(joe, 42)) vs Some(List(name:joe,age:42, null, null, joe, 42, null, null))。特别是当添加更多模式时

标签: scala thread-safety scala-collections


【解决方案1】:

我仍然觉得使用单个正则表达式模式可能会有优势。

val pattern = List("the name and age are (\\w+), (\\d+)"
                  ,"name:(\\w+),age:(\\d+)"
                  // add more as needed
                  ,"n=(\\w+),a=(\\d+)"
                  ).mkString("|").r

def transform(subject: String): Option[String] =
  pattern.findFirstMatchIn(subject)
         .map(_.subgroups.filter(_ != null).mkString)

【讨论】:

  • 如果有 1000 个模式怎么办?即使第一个模式匹配(最佳情况),.filter 也必须遍历所有模式
  • 确实如此,但是 1000 个单独编译的模式或 1000 个模式组合成一个编译,无论哪种方式,它都对正则表达式提出了很多要求。适当的解析器组合器可能是完成此类任务的更好工具。
猜你喜欢
  • 2013-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-26
  • 1970-01-01
  • 2013-05-24
  • 2016-07-24
相关资源
最近更新 更多