对集合进行增量(多次传递)过滤的理想集合是什么?

时间:2013-12-12 13:30:28

标签: scala scala-collections

我见过很多关于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)
 }
}

1 个答案:

答案 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)
  }
}