我有一个字符串列表。元素由两个字母组成。例如,
val A = List("bf", "dc", "ab", "af")
我想收集所有具有共同字母的字母,即
"bf" and "af" share "f"
放入元组
("a", "b", "f")
另一个元组应该是
("c", "d")
所以我想返回一个看起来像这样的列表
List(List("a", "b", "f"), List("c", "d"))
我得到了预期的结果
val A= List("bf", "dc", "ab", "af")
val B= A.flatMap(x => x.split("")).distinct
B.map(y => A.map(x => if(x.contains(y)) {x} else {""}).filter(_ !="").flatMap(_.split("")).distinct.sorted).distinct
但是必须有更好的方法。
答案 0 :(得分:0)
您的解决方案还不错,但是可以简化。
然后,您不必拆分字符串和flatMap。您可以将字符串列表放平。
A.map(x => if(x.contains(y)) {x} else {""}).filter(_!="")
最好写:
A.flatMap(x => if(x.contains(y)) Some(x) else None)
或
A.filter(_.contains(y))
但是您可以使用分区和计数来表达它,这是我的解决方案:
val a = List("bf", "dc", "ab", "af")
val b = a.flatten.distinct.sorted
b.partition(x => a.count(_.contains(x)) > 1)
答案 1 :(得分:0)
我很好奇,“ 更好”是什么意思?如果您关心以Big O表示的算法复杂性,请假设以下条件:
n
小得多。然后您可以在O(n)中完成此操作:
def fn(in: Iterator[String]) = {
val a = Array.fill(26)(-1)
for {s <- in} {
val cl = s.toSeq.map(_ - 'a')
val i = cl.map(a(_)).find(_ >= 0) getOrElse cl.head
cl.foreach(a(_) = i)
}
a.zipWithIndex.filter(_._1 > 0).groupBy(_._1).values.map {
_.map(_._2+'a').map(_.toChar)
}
}
scala> fn(List("bf", "dc", "ab", "af").toIterator)
res17: Iterable[Array[Char]] = List(Array(a, b, f), Array(c, d))
返回“ 更好”。如果您想要一个漂亮的FP解决方案,那么有人可能会说我们在这里牺牲了FP,因为使用了可变变量。 这是有争议的,因为该可变变量的作用域在内部,并且该函数仍然是纯函数。