List insertion order based on the next list

I have a sorting problem in Scala that I could solve with brute force, but I hope there is a smarter / more elegant solution. Suppose I have a list of strings without any special order:

val keys = List("john", "jill", "ganesh", "wei", "bruce", "123", "Pantera")

Then, in random order, I get the values ​​for these keys at random (full disclosure, I experience this problem with an aka actor, so the events are not in order):

def receive:Receive = {
  case Value(key, otherStuff) => // key is an element in keys ...

And I want to save these results in List, where the objects are Valuedisplayed in the same order as their fields keyin the list keys. For example, I may have this list after receiving the first two messages Value:

List(Value("ganesh", stuff1), Value("bruce", stuff2))

ganeshappears before brucejust because he appears earlier on the list keys. After receiving the third message, I must insert it in this list in the right place in the order established keys. For example, when receiving, weiI have to insert it in the middle:

List(Value("ganesh", stuff1), Value("wei", stuff3), Value("bruce", stuff2))

At any time during this process, my list may not be complete, but in the expected order. Since the keys are redundant with my data Value, I drop them as soon as the list of values ​​is complete.

Show me what you have!

+4
source share
2 answers

ListMap , . ListMap .

class MyActor(keys: List[String]) extends Actor {

  def initial(values: ListMap[String, Option[Value]]): Receive = {
    case v @ Value(key, otherStuff) =>
      if(values.forall(_._2.isDefined))
        context.become(valuesReceived(values.updated(key, Some(v)).collect { case (_, Some(v)) => v))
      else
        context.become(initial(keys, values.updated(key, Some(v))))
  }

  def valuesReceived(values: Seq[Value]): Receive = { } // whatever you need

  def receive = initial(keys.map { k => (k -> None) })

}

(: )

+1

, O(n log n). :

val order = keys.zipWithIndex.toMap
var part = collection.immutable.TreeSet.empty[Value](
  math.Ordering.by(v => order(v.key))
)

.

scala> part = part + Value("ganesh", 0.1)
part: scala.collection.immutable.TreeSet[Value] = 
  TreeSet(Value(ganesh,0.1))

scala> part = part + Value("bruce", 0.2)
part: scala.collection.immutable.TreeSet[Value] =
  TreeSet(Value(ganesh,0.1), Value(bruce,0.2))

scala> part = part + Value("wei", 0.3)
part: scala.collection.immutable.TreeSet[Value] = 
  TreeSet(Value(ganesh,0.1), Value(wei,0.3), Value(bruce,0.2))

, .toList . , , , , , , O(n^2).


: , 1/3 -. 25 1/10- . 1/30 200 ( 6 0,2 ).

+3

Source: https://habr.com/ru/post/1530697/


All Articles