2017-04-10 4 views
1

I이 스칼라 코드를 가지고 있지만 정렬 된 목록 제공하지 않습니다 : 나는스칼라 매끄러운 쿼리

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

인가 정렬 된 목록을 얻을 아래 난 단지이 회선을 사용하는 경우

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 
    } 
} 

을 join/groupBy 조작은 어떤 식 으로든 정렬에 영향을 줍니까?

+1

예 그들은 매우 큰 방식으로합니다. 따라서 정렬 된 결과가 필요하면 다시 정렬해야합니다. –

답변

1

TraversableLike.groupByimmutable.Map을 반환합니다. 실행 순서는 for -loop의 요소를 반복하므로 삽입 순서는 Map 값에 대해서만 유지됩니다. 반대의 키에는 실제로 순서가 없습니다. 이들은 제공된 기능의 결과입니다.

Scalas 표준 수집 라이브러리는이 문제에 대한 아웃 - 오브 - 박스 솔루션이 없습니다.

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에 위의 코드의 성능을 비교하지 않았다 나는 정확히 같은 문제를 가지고 있기 때문에 내가 대신 immutable.ListMap 반환 Seq 확장으로 orderedGroupBy 내 자신을 썼다. 내 목적에는 충분하지만 상황은 더 나쁠 수 있습니다. 어떤 개선도 환영합니다.

+0

훌륭함 - 스칼라에 익숙하지 않아도 될 필요가있는 것 – srvy

2

GroupBy는지도를 반환하므로 정렬 순서를 유지하지 않습니다. 이 동작은 Scala 컬렉션과 일치합니다.