【问题标题】:Scala fill in blank spaces in ListScala填充List中的空格
【发布时间】:2014-11-09 16:49:55
【问题描述】:

我正在使用 Scala Hadoop 版本,我需要使用第一个字段的先前值填充所有列表。现在看起来像这样:

List(This1, that1)

List(, that2)

List(, that3)

List(This2, that4)

List(, that1)

我希望它看起来像这样:

List(This1, that1)

List(This1, that2)

List(This1, that3)

List(This2, that4)

List(This2, that1)

更新: 我有一个演员和电影文本文件,我需要像这样获取它:

[ (Actor1, Movie1), (Actor1, Movie2), (Actor2, Movie3), (Actor3, Movie2), (Actor4, Movie3), (Actor4, Movie1) ]

文本文件如下所示(其中 | 表示用于区分演员和电影的“制表符”。)正如您所见,演员可以拥有多部电影,在电影之前不会提及演员。

$, Claw     |   "OnCreativity" (2012)  [Himself]

$, Homo     |   Nykytaiteen museo (1986)  [Himself]  <25>

        |   Suuri illusioni (1985)  [Guests]  <22>

$, Steve    |   E.R. Sluts (2003) (V)  <12>

$hort, Too  |   2012 AVN Awards Show (2012) (TV)  [Himself - Musical Guest]

        |   2012 AVN Red Carpet Show (2012) (TV)  [Himself]

所以我做了这个动作(演员之间也有空行,所以就是 !_.isEmpty 过滤器):

val test = actor.filter(!_.isEmpty).map(line => line.split("\t+").toList)

这将像上面的列表一样创建它。我对 Scala 还很陌生,所以我真的不知道如何正确地说出来。

【问题讨论】:

  • 列表“List(, that)”的第一个元素是什么?零?一个选项?一个空字符串?您的第一个列表中是否总是有一个有效的第一个元素? (比如This1)另外,你说的是“填写一个列表”,但你给出了很多列表——你有一个列表列表吗?
  • 里面什么都没有。它是按标签过滤的
  • 有点不清楚。请详细说明,“我希望它看起来像这样”是什么意思。您有一个 ListLists 并且您想将它们转换为一个新的 ListLists?这就是你想要的吗?
  • 如果您的列表有两个元素长,则不可能“无”。你是说你有一个二元素列表,然后是一些单元素列表,然后是另一个二元素列表?而且我不知道您所说的“按标签过滤”是什么意思
  • 我更新了问题,也许这有帮助

标签: list scala hadoop


【解决方案1】:

您的数据结构含糊不清,所以我将为您假设一些事情。

您将 Actor 作为字符串,将 Movie 作为字符串。每行表示为一对(演员,电影),并且您有一个此类对的列表。在某些对中,Actor 是一个空字符串 ""。您希望列表标准化,以便空字符串被前一对中的参与者替换。

def normalizeActorsMovies(in: List[(String, String)]): List[(String, String)] = {
  in match {
    case (actor, movie) :: ("", movie2) :: rest =>
      (actor, movie) :: normalizeActorsMovies( (actor, movie2) :: rest)
    case _ => in
  }
}

如果初始对有一个空的 Actor 字段,这显然不会做正确的事情,但您可以添加一些防弹。

【讨论】:

    【解决方案2】:

    这里有一个解决方案

    首先,列出我认为您拆分后的结果:

    val t = List(
    List("$, Claw", "\"OnCreativity\" (2012)  [Himself]"),
    List("$, Homo", "Nykytaiteen museo (1986)  [Himself]  <25>"),
    List("", "Suuri illusioni (1985)  [Guests]  <22>"),
    List("$, Steve", "E.R. Sluts (2003) (V)  <12>"),
    List("$hort, Too", "2012 AVN Awards Show (2012) (TV)  [Himself - Musical Guest]"),
    List("", "2012 AVN Red Carpet Show (2012) (TV)  [Himself]"))
    

    然后是代码 - 在foldLeft 中,我们保留了迄今为止的结果列表(为了提高效率,反过来),以及我们当前用于填充我们找到的任何空白第一个条目的值。如果我们得到一个非空白,我们用非空白的第一个条目替换那个值,否则我们继续使用它。末尾的._1.reverse 是按照正确的顺序从结果中检索修改后的列表。

    t.tail.foldLeft((List(t.head), t.head.head)) {
      case ((acc, previous), elem) =>
        val fill = if (elem.head.isEmpty) previous else elem.head
        ((fill :: elem.tail) :: acc, fill)
    }._1.reverse 
    //> res1: (List[List[String]], String) = (List(
    // List($, Claw, "OnCreativity" (2012)  [Himself]),
    // List($, Homo, Nykytaiteen museo (1986)  [Himself]  <25>),
    // List($, Homo, Suuri illusioni (1985)  [Guests]  <22>),
    // List($, Steve, E.R. Sluts (2003) (V)  <12>),
    // List($hort, Too, 2012 AVN Awards Show (2012) (TV)  [Himself - Musical Guest]),
    // List($hort, Too, 2012 AVN Red Carpet Show (2012) (TV)  [Himself]))
    

    【讨论】: