에 의해 목록은 우리가 나는 다음과 같은 두 시퀀스가 있다고 가정하자정렬 순서 인덱스
val index = Seq(2,5,1,4,7,6,3)
val unsorted = Seq(7,6,5,4,3,2,1)
첫 번째는 두 번째 정렬해야하는 인덱스입니다. 내 현재 솔루션은 인덱스를 탐색하고 정렬되지 않은 시퀀스에서 발견 된 요소를 사용하여 새 시퀀스를 구성하는 것입니다.
val sorted = index.foldLeft(Seq[Int]()) { (s, num) =>
s ++ Seq(unsorted.find(_ == num).get)
}
그러나이 솔루션은 매우 비효율적이며 오류가 발생하는 것으로 보입니다. 매 반복마다 정렬되지 않은 전체 시퀀스를 검색합니다. 그리고 인덱스와 정렬되지 않은 목록이 동기화되어 있지 않으면 오류가 발생하거나 요소가 생략됩니다. 두 경우 모두 not in sync 요소는 정렬 된 순서에 추가되어야합니다.
이 문제에 대한보다 효과적이고 확실한 해결책이 있습니까? 아니면이 패러다임에 맞는 정렬 알고리즘이 있습니까?
주 :이 구성 예이다. 실제로 mongodb 문서의 목록을 문서 ID의 정렬 된 목록으로 정렬하고 싶습니다. 내 문제에 대한 더 빠르고 스칼라 틱 솔루션을 보이기 때문에
업데이트 1
나는 마리우스 다닐라에서 답을 선택했습니다. 그것은 동기화 항목 솔루션과 함께 제공되지 않습니다,하지만 쉽게 구현할 수 있습니다.
그래서 여기에 업데이트 된 솔루션입니다 :
def sort[T: ClassTag, Key](index: Seq[Key], unsorted: Seq[T], key: T => Key): Seq[T] = {
val positionMapping = HashMap(index.zipWithIndex: _*)
val inSync = new Array[T](unsorted.size)
val notInSync = new ArrayBuffer[T]()
for (item <- unsorted) {
if (positionMapping.contains(key(item))) {
inSync(positionMapping(key(item))) = item
} else {
notInSync.append(item)
}
}
inSync.filterNot(_ == null) ++ notInSync
}
업데이트 2
Bask.cc에 의해 제안 접근 정답을 보인다. 또한 동기화되지 않은 문제는 고려하지 않지만 쉽게 구현할 수도 있습니다.
val index: Seq[String]
val entities: Seq[Foo]
val idToEntityMap = entities.map(e => e.id -> e).toMap
val sorted = index.map(idToEntityMap)
val result = sorted ++ entities.filterNot(sorted.toSet)
당신은 불변 dafault'Seq'은 임시 객체를 많이 구축 결국를 사용하는 경우 . – monnef
@flavian 나는 데이터베이스에 질의하는데 reactivemongo를 사용한다. 하지만 $ orderBy를 사용하여 외부 색인으로 정렬 할 수 있습니까? 나는 오름차순 또는 내림차순으로 필드로만 정렬 할 수 있다고 생각했습니다. 문서의 순서를 저장할 수 있지만 위치가 변경된 경우 모든 문서를 업데이트해야합니다. 현재의 솔루션으로는 새로운 인덱스 만 생성합니다. – akkie