我有一个scala List,其中包含一个字符串和一个整数列表。我想只过滤那些整数列表最大的那些。从最高和最低排序,然后取n个字符串的常用方法有一个缺点。
var qq = List[(String,List[Int])]()
比如说长度为10的List,有6个大小为65的列表,其余5个大小小于65.现在我需要从向量中检索所有6个列表。
方法:传统方式是对列表进行排序,获取最高列表的大小并添加具有该大小的过滤条件。
var max = qq.sortWith(_._2.size>_._2.size).head._2.size //get maximum size
var filList = qq.filter(p=>p._2.size>=max) //filter them
我的问题是在scala中还有其他快速有效的方法吗?正如我所做的那样,处理大约10,000-20,000次,列表大小更大。
答案 0 :(得分:2)
对于性能,如果您只想要最大值,则不应对整个列表进行排序。
其次,在Scala中使用多线程代码非常容易:
val data = List(("a", List(1, 2, 3)), ("b", List(4, 5)), ("c", List(45, 3, 2)))
val maxListSize = data.par.map(_._2.size).max
val largestLists = data.par.filter(_._2.size == maxListSize)
println(largestLists)
只需添加.par
(并行集合)即可实现多线程。请注意,除非您有非常大的列表,否则您可能希望删除这些.par
,因为它们可能会减慢速度。对于大型列表,并行化将提供加速因子,即计算机上的核心数。
答案 1 :(得分:1)
我建议
val sorted = qq.sortBy(_._2.size)
val thresh = sorted.head._2.size // assume qq is non-empty
val retain = sorted.takeWhile(_._2.size == thresh)
任何情况下的表现都受到排序程序的约束(当然比O(N)差)。
另一种方法是在不进行排序的情况下构建结果。只需跟踪最佳结果,并在检测到更大尺寸的列表时替换它们。
像这样:
type A = (String,List[Int])
((0, List.empty[A]) /: qq) { case (prev @ (bestLen, res), entry @ (_, list)) =>
val eLen = list.size
if (eLen < bestLen) prev
else if (eLen == bestLen) (bestLen, entry :: res)
else (eLen, entry :: Nil)
}
表现将是O(N),尽可能好。