我对scala(以及一般的编程)都很陌生,但是我想出了一个不太完美的解决方案来解决我遇到的问题 - 我想知道是否有人更优雅/高效?< / p>
我有一个(非常大的)字符串集,下面的一个小例子用于复制目的:
val brands = Set("Brand one", "BRAND-two!!!", "brand_Three1, brandThree2", "brand04")
现在我要做的是清理这个集合,以便我有一个新的干净集:
到目前为止,我所做的代码都是这样做的,但它分两步完成,因此在列表上迭代两次(效率很低):
val brands_clean = brands.flatMap(
_.toLowerCase.split(",").map(
_.trim.replaceAll("[^A-Za-z0-9\\-\\_\\s]+", "")
)
)
def spaceVariations(v: String) = if (v.contains(" ")) Set(v.replaceAll(" ", "-"), v.replaceAll(" ", "_"), v.replaceAll(" ", "")) else Set(v)
val brands_final = brands_clean.flatMap(spaceVariations(_))
我尝试将spaceVariations函数直接合并到主代码中,方法是将replaceAll附加到map或flatMap:
// using the function call
.flatMap(spaceVariations(_))
// or using a function directly within the code
.flatMap {v => if (v.contains(" ")) Set(v.replaceAll(" ", "-"), v.replaceAll(" ", "_"), v.replaceAll(" ", "")) else Set(v) }
但是我收到以下错误:
error: type mismatch;
found : Array[Nothing]
required: scala.collection.GenTraversableOnce[?]
我不确定我理解为什么这在这里不起作用,或者是否有更好的方法来实现我想要实现的目标?
答案 0 :(得分:3)
brands.flatMap(
_.toLowerCase.split(",").map(
_.trim.replaceAll("""[^\w-]""", "")
)
).flatMap(spaceVariations)
为我工作,不知道你在哪里(或为什么)得到错误(我清理了你的正则表达式,使它更简洁,但这不重要)。
请注意,此仍然遍历该集两次。在scala中集合不是懒惰的,因此,它将首先使用中间集合完成第一个flatMap
,然后从下一个集合开始。
如果要保存扫描,则应该以{{1}}而不是集合开头,因为迭代器是惰性的,并且会在继续下一个之前将每个元素发送到整个链:
Iterator
答案 1 :(得分:1)
基于您Set
将始终如此的假设:
def spaceVariations(v: String) = if (v.contains(" ")) Set(v.replaceAll(" ", "-"), v.replaceAll(" ", "_"), v.replaceAll(" ", "")) else Set(v)
val brands = Set("Brand one", "BRAND-two!!!", "brand_Three1, brandThree2", "brand04")
brands.map( x => if (x.contains(",") ) x.split(",") else x ).flatMap {
case str: String => Array(str)
case a : Array[String] => a
}.map(_.trim.toLowerCase.replaceAll("[^A-Za-z0-9\\-\\_\\s]+", "")).map(spaceVariations(_))
给出输出:
Set(Set(brand-one, brand_one, brandone), Set(brandthree2), Set(brand04), Set(brand-two), Set(brand_three1))