Scala:如何正确重新排序列表?

时间:2014-10-13 20:41:30

标签: scala

我们说我有一个Scala的对象列表。每个对象都是一个由整数索引和字符串组成的案例类。

case class Item(index: Integer, name: String)

我有这个列表,例如,五个项目。每个项目都有一个数字索引和字符串中的一些值。

List(Item(0, "foo"), Item(1, "bar"), Item(2, "baz"), Item(3, "foobie"), Item(4, "blech"))

我已经决定我喜欢"插槽3"进入" 1号槽。"所以我想做的不仅是将插槽3中的项目索引设置为1,而且我还希望通过推送所有内容来对List进行物理重新排序。换句话说,"推广"一个项目稍后在靠近开头的列表中。我最终会:

List(Item(0, "foo"), Item(1, "foobie"), Item(2, "bar"), Item(3, "baz"), Item(4, "blech"))

当然,我可以通过常规方式使用数组和var来实现这一点,但是如果我想使用不可变列表并且只是创建一个新的,那么地图是否有一个很好的,可用的语法可以帮助我做这个?或者是否有某种功能性的方法来正确地做到这一点?

1 个答案:

答案 0 :(得分:2)

嗯,你走了,虽然我不喜欢它。

从您的评论中,索引值可能有间隙,因此不是列表中的位置。所以我们可以不假设它们,所以这只是提取它们(和字符串),操作字符串列表,然后从索引列表和结果列表中构建项目。

case class Item(index: Integer, name: String)
val xs = List(Item(0, "foo"), Item(1, "bar"), Item(2, "baz"), Item(3, "foobie"), Item(4, "blech"))

def move(xs: List[Item], src:Int, dst:Int) = {
    val strings = xs.map(_.name)
    val indices = xs.map(_.index)
    val (prefix, d::rest) = strings splitAt(dst)
    val (middle, s::suffix) = rest splitAt(src-dst-1)
    (indices zip (prefix ++ List(s) ++ List(d) ++ middle ++ suffix))
       map  {case (i, s) => Item (i, s)}
}
move (xs, 3, 1)
//> res0: List[lists.lists2.Item] = List(Item(0,foo), Item(1,foobie), 
                                         Item(2,bar), Item(3,baz), Item(4,blech))