List 基于另一个列表顺序的列表插入顺序
我在Scala中有一个排序问题,我当然可以用蛮力解决,但我希望有一个更聪明/优雅的解决方案可用。假设我有一个没有特定顺序的字符串列表:List 基于另一个列表顺序的列表插入顺序,list,scala,data-structures,functional-programming,akka,List,Scala,Data Structures,Functional Programming,Akka,我在Scala中有一个排序问题,我当然可以用蛮力解决,但我希望有一个更聪明/优雅的解决方案可用。假设我有一个没有特定顺序的字符串列表: val keys=List(“约翰”、“吉尔”、“甘尼什”、“魏”、“布鲁斯”、“123”、“潘太拉”) 然后随机地,我随机地收到这些键的值(完全公开,我在akka演员身上遇到了这个问题,所以事件不符合顺序): def接收:接收={ 大小写值(key,otherStuff)=>//key是key中的一个元素。。。 我想将这些结果存储在列表中,其中值对象的显示
val keys=List(“约翰”、“吉尔”、“甘尼什”、“魏”、“布鲁斯”、“123”、“潘太拉”)
然后随机地,我随机地收到这些键的值(完全公开,我在akka演员身上遇到了这个问题,所以事件不符合顺序):
def接收:接收={
大小写值(key,otherStuff)=>//key是key中的一个元素。。。
我想将这些结果存储在列表
中,其中值
对象的显示顺序与键
列表中的键
字段的显示顺序相同。例如,我可能在收到前两条值
消息后拥有此列表:
列表(值(“ganesh”,填充1),值(“bruce”,填充2))
ganesh
出现在bruce
之前,仅仅是因为他出现在keys
列表的前面。一旦收到第三条消息,我应该按照keys
建立的顺序将其插入此列表的正确位置。例如,在收到wei
时,我应该将他插入中间:
列表(值(“ganesh”,填充1),值(“wei”,填充3),值(“bruce”,填充2))
在此过程中的任何时候,我的列表都可能不完整,但顺序符合预期。由于键与我的值
数据是冗余的,因此一旦值列表完成,我就会将它们丢弃
告诉我你有什么!如果你可以在收集值时使用列表映射而不是元组列表来存储值,这可能会起作用。列表映射保留插入顺序
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) })
}
(警告:未编译)我假设您想要的性能不比
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)
成本
编辑:以您的七个项目为例,我的解决方案大约需要Jean-Philippe的1/3时间。对于25个项目,这是时间的1/10。对于200个项目,这是时间的1/30(在我的机器上是6毫秒和0.2毫秒之间的差).天啊,我从来不知道
ListMap
。我有Java背景,我一直希望Scala有一个不可变的LinkedHashMap
。这两个答案都很出色,但碰巧我采用了ListMap
方法,因为它在我的情况下更有意义。我将我的映射定义为ListMap[String,Option][值]]
将所有值初始化为None
。我用一些[值]填充它们
他们进来了。多亏了@Ryan和@RexKerr!我考虑过创建一个排序
,但觉得可能太贵了。我知道你以前已经考虑过了。好消息!@barnesjd-创建排序
需要几十纳秒。你是否最好创建哈希映射(大约需要一微秒)或者仅仅遍历列表取决于列表的长度。很好的解决方案!我的解决方案绝对没有比这更好的,所以我将删除它。