Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Scala根据另一个列表中的值对一个列表进行排序_List_Scala - Fatal编程技术网

List Scala根据另一个列表中的值对一个列表进行排序

List Scala根据另一个列表中的值对一个列表进行排序,list,scala,List,Scala,我有两个指数 works[Work] order[Int] 每个对象工作都有一个id字段,其整数值为:Work.id 在订单列表中有ID,它们是按照我们需要排序工作的顺序排列的。比如,在位置0中有第一个id,所以我们需要在works数组中找到id与此id对应的工作,并将其放在0处,以此类推。 有没有办法不用经过两个循环就可以使用scala实现这一点?比如,某种优雅的方式? 一些伪数据,例如: order = 33, 22, 11, 55 works = (33, "some text"),

我有两个指数

works[Work]
order[Int]
每个对象工作都有一个id字段,其整数值为:Work.id 在订单列表中有ID,它们是按照我们需要排序工作的顺序排列的。比如,在位置0中有第一个id,所以我们需要在works数组中找到id与此id对应的工作,并将其放在0处,以此类推。 有没有办法不用经过两个循环就可以使用scala实现这一点?比如,某种优雅的方式? 一些伪数据,例如:

order = 33, 22, 11, 55

works = (33, "some text"), (55, "eeeee"), (22, "fdsfs"), (11, "fdsffds")
case class Work(id: Int, text: String)
// defined class Work

val order = Seq(33, 22, 11, 55)
// order: Seq[Int] = List(33, 22, 11, 55)

val works = Seq(Work(33, "some text"), Work(55, "eeeee"), Work(22, "fdsfs"), Work(11, "fdsffds"))
// works: Seq[Work] = List(Work(33, "some text"), Work(55, "eeeee"), Work(22, "fdsfs"), Work(11, "fdsffds"))

val workMap = works.map(work => work.id -> work).toMap
// workMap: Map[Int, Work] = Map(33 -> Work(33, "some text"), 55 -> Work(55, "eeeee"), 22 -> Work(22, "fdsfs"), 11 -> Work(11, "fdsffds"))

order.collect(workMap)
// res14: Seq[Work] = List(Work(33, "some text"), Work(22, "fdsfs"), Work(11, "fdsffds"), Work(55, "eeeee"))
排序后:

order = 33, 22, 11, 55

works = (33, "some text"),(22, "fdsfs"),  (11, "fdsffds"), (55, "eeeee"),

您可以使用字典,这里的复杂度是O(N)(与两个嵌套循环的N*N相比,这更好):

如果实体不仅仅是元组:

scala> val worksMap = (works map (_._1) zip works).toMap //any other key extraction, like `_.myKey` may be applied instead of `_._1`
worksMap: scala.collection.immutable.Map[Int,(Int, String)] = Map(33 -> (33,some text), 55 -> (55,eeeee), 22 -> (22,fdsfs), 11 -> (11,fdsffds))

scala> order.map(worksMap)
res13: List[(Int, String)] = List((33,some text), (22,fdsfs), (11,fdsffds), (55,eeeee))
如果您不想为
Map
花费内存,只需使用find而不是
Map.apply
(但它将是O(N*N),因此速度较慢):

如果您不想在
订单
不包含您的密钥的情况下出现异常,您可以使用
平面图

scala> val newWorks = order.flatMap(x => works.find(_._1 == x))
newWorks: List[(Int, String)] = List((33,some text), (22,fdsfs), (11,fdsffds), (55,eeeee))

scala> order.flatMap(worksMap.get)
res15: List[(Int, String)] = List((33,some text), (22,fdsfs), (11,fdsffds), (55,eeeee))
val works = Seq(Work(33, "a"), Work(34, "b"), Work(33, "c"), Work(35, "d"))
// works: Seq[Work] = List(Work(33, "a"), Work(34, "b"), Work(33, "c"), Work(35, "d"))

val worksMap = works.groupBy(_.id)
//worksMap: Map[Int, Seq[Work]] = Map(35 -> List(Work(35, "d")), 34 -> List(Work(34, "b")), 33 -> List(Work(33, "a"), Work(33, "c")))

val order = Seq(35, 34, 33)
//order: Seq[Int] = List(35, 34, 33)

order.flatMap(id => worksMap.getOrElse(id, Seq.empty))
// res23: Seq[Work] = List(Work(35, "d"), Work(34, "b"), Work(33, "a"), Work(33, "c"))

您可能对
sortWith
方法感兴趣:

works.sortWith((a, b) => order.indexOf(a._1) < order.indexOf(b._1))
works.sortWith((a,b)=>order.indexOf(a._1)
假设您的数据在
列表中,您可以执行以下操作:

scala> val order = List(33, 22, 11, 55)
order: List[Int] = List(33, 22, 11, 55)

scala> val works = List((33, "some text"), (55, "eeeee"), (22, "fdsfs"), (11, "fdsffds"))
works: List[(Int, String)] = List((33,some text), (55,eeeee), (22,fdsfs), (11,fdsffds))

scala> val sortedWorks = order.flatMap( id => works.find(x => x._1 == id ))
sortedWorks: List[(Int, String)] = List((33,some text), (22,fdsfs), (11,fdsffds), (55,eeeee))
现在,您可以使用映射来选择按id查找工件的零件,这将使其如下所示:

scala> val worksMap = works.toMap
worksMap: scala.collection.immutable.Map[Int,String] = Map(33 -> some text, 55 -> eeeee, 22 -> fdsfs, 11 -> fdsffds)

scala> val sortedWorks = order.flatMap( id => worksMap.get(id))
sortedWorks: List[String] = List(some text, fdsfs, fdsffds, eeeee)

性能将取决于查找。在这种情况下,由于HashMap,它被摊销为O(N)。

您可以将
Seq[Work]
转换为
Map[WorkId,Work]
,并
按照与
Seq[WorkId]
相同的顺序从映射中收集值

例如:

order = 33, 22, 11, 55

works = (33, "some text"), (55, "eeeee"), (22, "fdsfs"), (11, "fdsffds")
case class Work(id: Int, text: String)
// defined class Work

val order = Seq(33, 22, 11, 55)
// order: Seq[Int] = List(33, 22, 11, 55)

val works = Seq(Work(33, "some text"), Work(55, "eeeee"), Work(22, "fdsfs"), Work(11, "fdsffds"))
// works: Seq[Work] = List(Work(33, "some text"), Work(55, "eeeee"), Work(22, "fdsfs"), Work(11, "fdsffds"))

val workMap = works.map(work => work.id -> work).toMap
// workMap: Map[Int, Work] = Map(33 -> Work(33, "some text"), 55 -> Work(55, "eeeee"), 22 -> Work(22, "fdsfs"), 11 -> Work(11, "fdsffds"))

order.collect(workMap)
// res14: Seq[Work] = List(Work(33, "some text"), Work(22, "fdsfs"), Work(11, "fdsffds"), Work(55, "eeeee"))
这与其他答案类似,但使用了
collect
,因为
Map[A,B]
也是一个
PartialFunction[A,B]


但是,上述解决方案假定工作ID是唯一的

如果工作ID不唯一,可以使用
groupBy
flatMap

scala> val newWorks = order.flatMap(x => works.find(_._1 == x))
newWorks: List[(Int, String)] = List((33,some text), (22,fdsfs), (11,fdsffds), (55,eeeee))

scala> order.flatMap(worksMap.get)
res15: List[(Int, String)] = List((33,some text), (22,fdsfs), (11,fdsffds), (55,eeeee))
val works = Seq(Work(33, "a"), Work(34, "b"), Work(33, "c"), Work(35, "d"))
// works: Seq[Work] = List(Work(33, "a"), Work(34, "b"), Work(33, "c"), Work(35, "d"))

val worksMap = works.groupBy(_.id)
//worksMap: Map[Int, Seq[Work]] = Map(35 -> List(Work(35, "d")), 34 -> List(Work(34, "b")), 33 -> List(Work(33, "a"), Work(33, "c")))

val order = Seq(35, 34, 33)
//order: Seq[Int] = List(35, 34, 33)

order.flatMap(id => worksMap.getOrElse(id, Seq.empty))
// res23: Seq[Work] = List(Work(35, "d"), Work(34, "b"), Work(33, "a"), Work(33, "c"))

把它们拉到一起,分类,然后再解压?听起来很奇怪,这到底是怎么回事?肯定有办法。发布
IndexedSeq
工作的
订单的示例数据以及您希望输出的样子。我非常喜欢第二个示例的外观,让我测试一下:)这里的复杂性是关于
O(N*N*logN)>O(N*N)
,因为
indexOf
是线性的,在这种情况下效率很低,但我只是想提出
sortWith
方法,在许多小案例中,复杂性不如可读性重要!正如我所说,“只是提一下”,没有批评:)这实际上应该被标记为正确的答案,它非常简单,效果非常好。