Scala光滑查询未排序

时间:2017-04-10 06:02:26

标签: scala playframework slick

我有这个Scala代码,但它没有给出排序列表:

def getItemsByCategoryId(catId: Long, start: Int = 0, limit: Option[Int] = None): Future[Seq[(Item, Seq[String])]] = {

  val itemList = items.sortBy(_.name).filter(_.categoryId === catId).drop(start)

  val q = for {
    (j, pair) <- itemList joinLeft (groups join tags on (_.tagId === _.id)) on (_.id === _._1.itemId)
  } yield (j, pair)

  db.run(q.result).map { (row) =>
    row.groupBy(_._1).map { x =>
      val tags = x._2.map(_._2).flatten
      (x._1, tags.map(_._2.keyword))
    }.toSeq
  }
}

如果我只使用下面这一行,我会得到排序列表

val itemList = items.sortBy(_.name).filter(_.categoryId === catId).drop(start)

join / groupBy操作是否会以某种方式影响排序?

2 个答案:

答案 0 :(得分:2)

GroupBy在返回地图时不会保留排序。此行为与Scala集合一致。

答案 1 :(得分:1)

TraversableLike.groupBy会返回immutable.Map。仅为Map值保留插入顺序,因为实现在for循环中迭代其元素。对面的钥匙确实没有订单。它们是提供的功能的结果。

Scalas标准集合库没有针对此问题的开箱即用解决方案。由于我遇到了完全相同的问题,因此我编写了自己的orderedGroupBy作为Seq的扩展名,而immutable.ListMap代替了implicit class SeqWithOrderedGroupBy[A](xs: Seq[A]) { /** * Partitions this traversable collection into a map of traversable collections according to some discriminator function. * Preserves insertion order. * * @param f the discriminatior function. * @tparam K the type of keys returned by the discriminator function. * @return An ordered map from keys to seq. */ def orderedGroupBy[K](f: A => K): immutable.ListMap[K, Seq[A]] = { val m = mutable.ListBuffer.empty[(K, mutable.Builder[A, Seq[A]])] for (elem <- xs) { val key = f(elem) val builder = m.find(_._1 == key) .map(_._2) .getOrElse { val bldr = mutable.Seq.newBuilder[A] m.append((key, bldr)) bldr } builder += elem } val b = immutable.ListMap.newBuilder[K, Seq[A]] for ((k, v) <- m) b += ((k, v.result)) b.result } }

TraversableLike.groupBy

免责声明:我没有将上述代码段的效果与users: sammy: status: employed chris: status: unemployed dan: status: employed 进行比较。这对我的目的来说已足够,但可能会更糟。不过,欢迎任何改进。