我见过很多关于Scala集合的问题但无法决定。 到目前为止,此question是最有用的。
我认为问题的核心是双重的: 1)这个用例的最佳集合是什么? 2)推荐使用哪种方法?
详细说明:
我正在实现一种迭代集合中所有元素的算法 搜索符合特定标准的那个。 搜索之后,下一步是再次使用新标准进行搜索,但在可能性中没有选择的元素。 我们的想法是创建一个序列,其中包含按标准排序的所有原始元素(在每个新选择时都会更改)。 原始序列并不需要进行排序,但可能存在重复(算法一次只能选择一个)。 一小部分Ints的例子(只是为了简化):
object Foo extends App {
def f(already_selected: Seq[Int])(element: Int): Double =
// something more complex happens here,
// specially something take takes 'already_selected' into account
math.sqrt(element)
//call to the algorithm
val (result, ti) = Tempo.time(recur(Seq.fill(9900)(Random.nextInt), Seq()))
println("ti = " + ti)
//algorithm
def recur(collection: Seq[Int], already_selected: Seq[Int]): (Seq[Int], Seq[Int]) =
if (collection.isEmpty) (Seq(), already_selected)
else {
val selected = collection maxBy f(already_selected)
val rest = collection diff Seq(selected) //this part doesn't seem to be efficient
recur(rest, selected +: already_selected)
}
}
object Tempo {
def time[T](f: => T): (T, Double) = {
val s = System.currentTimeMillis
(f, (System.currentTimeMillis - s) / 1000d)
}
}
答案 0 :(得分:0)
尝试@inline和icn建议How can I idiomatically "remove" a single element from a list in Scala and close the gap?:
object Foo extends App {
@inline
def f(already_selected: Seq[Int])(element: Int): Double =
// something more complex happens here,
// specially something take takes 'already_selected' into account
math.sqrt(element)
//call to the algorithm
val (result, ti) = Tempo.time(recur(Seq.fill(9900)(Random.nextInt()).zipWithIndex, Seq()))
println("ti = " + ti)
//algorithm
@tailrec
def recur(collection: Seq[(Int, Int)], already_selected: Seq[Int]): Seq[Int] =
if (collection.isEmpty) already_selected
else {
val (selected, i) = collection.maxBy(x => f(already_selected)(x._2))
val rest = collection.patch(i, Nil, 1) //this part doesn't seem to be efficient
recur(rest, selected +: already_selected)
}
}
object Tempo {
def time[T](f: => T): (T, Double) = {
val s = System.currentTimeMillis
(f, (System.currentTimeMillis - s) / 1000d)
}
}