【问题标题】:Scala: How to properly reorder a list?Scala:如何正确地重新排序列表?
【发布时间】:2014-12-08 12:31:46
【问题描述】:

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

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

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

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

我决定将“slot 3”中的项目放在“slot 1”中。所以我想要做的不仅是将插槽 3 中项目的索引设置为 1,而且我还想通过将所有内容向下推来对列表进行物理重新排序。换句话说,在靠近开始的列表中稍后“提升”一个项目。我最终会得到:

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

当然,我可以以通常的方式使用数组和 var 来做到这一点,但如果我想使用不可变列表并简单地创建一个新列表,是否有一种不错的函数式 map 语法可以帮助我做到这一点这?还是有某种功能性的方法可以正确地做到这一点?

【问题讨论】:

  • 为什么要在Item中保留索引而不仅仅是名称? (这样会更容易)
  • 虽然这是个好问题,但与询问如何重新排序无关。并假设我需要保留索引,这就是我将它放在那里的原因。我需要重新排序列表并在执行此操作时修改该字段。这里的推理是,每个 Item 都可以在 List 中的上下文之外使用,并且消费者需要知道索引。因此,项目必须知道。
  • @ChristopherAmbler 构建一个不是那么容易解决的示例而不是告诉某人您不喜欢他们的方法会很有帮助,因为真正的限制将有助于为实际适用于您的实际问题的解决方案提供信息。鉴于您提供的信息,我会执行 reorder(myList.map(_.name)).zipWithIndex.map(pair => Item(pair._2, pair._1),其中 reorder 是 List[String] => List[String] 类型的某个函数,用于实现您未指定的逻辑。
  • 我不清楚。没有其他逻辑。输入是一个列表和两个整数。第一个整数是我要移动的列表条目的槽位,第二个整数是我希望它在的槽位。Item的结构正是我想要的,并且指定了更改索引参数的要求.我遗漏了什么?我只是解释了为什么我以我的方式概述它。但据我所知,真正的限制都在原始问题中,不是吗?
  • @ChristopherAmbler,问题是如果索引值始终是列表中项目的位置,为什么您希望项目保存索引。这是多余的,意味着我们必须在项目移动时重新创建项目,而不是仅仅移动现有项目。项目可以知道它们在列表中的位置,而无需将其存储为成员 - 'index` 方法可以在列表中查找自身。

标签: scala


【解决方案1】:

好吧,给你吧,虽然我不太喜欢它。

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

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))

【讨论】:

  • 是的,事实证明,Item 中的索引可能存在间隙。所以这可以适应。
  • 好的。因此,鉴于 Items 是不可变的,无论如何我们都必须重新创建 src 和 dst 之间的所有 Items。所以这创造了一些不必要的东西,但相当简洁
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-24
  • 1970-01-01
  • 2019-09-18
  • 2021-12-07
  • 1970-01-01
  • 2011-01-11
相关资源
最近更新 更多