Note that there are some explanatory texts on larger screens.

plurals
  1. POSort a list by an ordered index
    primarykey
    data
    text
    <p>Let us assume that I have the following two sequences:</p> <pre><code>val index = Seq(2,5,1,4,7,6,3) val unsorted = Seq(7,6,5,4,3,2,1) </code></pre> <p>The first is the index by which the second should be sorted. My current solution is to traverse over the index and construct a new sequence with the found elements from the unsorted sequence.</p> <pre><code>val sorted = index.foldLeft(Seq[Int]()) { (s, num) =&gt; s ++ Seq(unsorted.find(_ == num).get) } </code></pre> <p>But this solution seems very inefficient and error-prone to me. On every iteration it searches the complete unsorted sequence. And if the index and the unsorted list aren't in sync, then either an error will be thrown or an element will be omitted. In both cases, the not in sync elements should be appended to the ordered sequence.</p> <p>Is there a more efficient and solid solution for this problem? Or is there a sort algorithm which fits into this paradigm?</p> <hr> <p><strong>Note</strong>: This is a constructed example. In reality I would like to sort a list of mongodb documents by an ordered list of document Id's.</p> <hr> <p><strong>Update 1</strong></p> <p>I've selected the answer from Marius Danila because it seems the more fastest and scala-ish solution for my problem. It doesn't come with a not in sync item solution, but this could be easily implemented.</p> <p>So here is the updated solution:</p> <pre><code>def sort[T: ClassTag, Key](index: Seq[Key], unsorted: Seq[T], key: T =&gt; Key): Seq[T] = { val positionMapping = HashMap(index.zipWithIndex: _*) val inSync = new Array[T](unsorted.size) val notInSync = new ArrayBuffer[T]() for (item &lt;- unsorted) { if (positionMapping.contains(key(item))) { inSync(positionMapping(key(item))) = item } else { notInSync.append(item) } } inSync.filterNot(_ == null) ++ notInSync } </code></pre> <hr> <p><strong>Update 2</strong></p> <p>The approach suggested by Bask.cc seems the correct answer. It also doesn't consider the not in sync issue, but this can also be easily implemented.</p> <pre><code>val index: Seq[String] val entities: Seq[Foo] val idToEntityMap = entities.map(e =&gt; e.id -&gt; e).toMap val sorted = index.map(idToEntityMap) val result = sorted ++ entities.filterNot(sorted.toSet) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload