Chúng ta hãy giả định rằng tôi có hai chuỗi sau:Sắp xếp một danh sách bằng một chỉ số lệnh
val index = Seq(2,5,1,4,7,6,3)
val unsorted = Seq(7,6,5,4,3,2,1)
Đầu tiên là chỉ số mà thứ hai nên được sắp xếp. Giải pháp hiện tại của tôi là duyệt qua chỉ mục và xây dựng một chuỗi mới với các phần tử tìm thấy từ chuỗi chưa phân loại.
val sorted = index.foldLeft(Seq[Int]()) { (s, num) =>
s ++ Seq(unsorted.find(_ == num).get)
}
Nhưng giải pháp này có vẻ rất không hiệu quả và dễ bị lỗi. Trên mỗi lần lặp lại, nó tìm kiếm toàn bộ chuỗi chưa phân loại. Và nếu chỉ mục và danh sách chưa được phân loại không đồng bộ, thì một lỗi sẽ bị ném hoặc một phần tử sẽ bị bỏ qua. Trong cả hai trường hợp, các phần tử không đồng bộ nên được nối vào trình tự được sắp xếp.
Có giải pháp hiệu quả và vững chắc hơn cho vấn đề này không? Hoặc là có một thuật toán sắp xếp phù hợp với mô hình này?
Lưu ý: Đây là ví dụ được tạo. Trong thực tế, tôi muốn sắp xếp một danh sách các tài liệu mongodb bởi một danh sách thứ tự của tài liệu Id.
Cập nhật 1
Tôi đã chọn câu trả lời từ Marius Danila vì nó có vẻ là giải pháp nhanh nhất và scala-ish hơn cho vấn đề của tôi. Nó không đi kèm với một giải pháp không đồng bộ trong mục, nhưng điều này có thể dễ dàng thực hiện.
Vì vậy, đây là giải pháp Cập nhật:
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
}
Cập nhật 2
Phương pháp được đề xuất bởi Bask.cc dường như câu trả lời đúng. Nó cũng không xem xét vấn đề không đồng bộ, nhưng điều này cũng có thể được thực hiện dễ dàng.
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)
Ngoài ra nếu bạn đang sử dụng dafault bất biến 'Seq' bạn kết thúc xây dựng rất nhiều đối tượng tạm thời . – monnef
@flavian Tôi sử dụng reactivemongo để truy vấn cơ sở dữ liệu. Nhưng tôi có thể sử dụng $ orderBy để sắp xếp với chỉ mục bên ngoài không? Tôi nghĩ rằng tôi chỉ có thể sắp xếp theo một trường theo thứ tự tăng dần hoặc giảm dần. Tôi có thể lưu thứ tự trong các tài liệu, nhưng sau đó tôi phải cập nhật tất cả các tài liệu nếu một vị trí đã thay đổi. Với giải pháp hiện tại tôi chỉ tạo một chỉ mục mới. – akkie