【问题标题】:Map letter to word in which it appears将字母映射到它出现的单词
【发布时间】:2019-08-26 10:34:55
【问题描述】:

我是 scala 的新手,我正在尝试编写一个函数,该函数接受输入字符串并将字母映射返回到它们出现的单词。

例如给定输入字符串"this is demo", 我想要输出映射['t'->["this"],'h'->["this],'i'->["this","is"]...等等。

我可以用传统的方式编写这段代码,但是我怎样才能通过使用 map、groupby、flatmap 等 scala 构造以函数方式编写这段代码?

【问题讨论】:

    标签: scala


    【解决方案1】:
    "this is demo"
      .split(" ")
      .flatMap(w => w.map(c => c -> w))
      .groupMap(_._1)(_._2)
    // HashMap(e -> Array(demo), s -> Array(this, is), t -> Array(this), m -> Array(demo), i -> Array(this, is), h -> Array(this), o -> Array(demo), d -> Array(demo))
    
    • 第一步包括获取一个元组数组,表示每个字符来自哪个单词。这可以通过首先将句子拆分为单词并为每个单词的每个字符生成一个包含字符及其单词的元组 (.map(w => w.map(c => c -> w))) 来实现。由于这给了我们一个数组数组,我们可以使用flatMap 将它们展平成一个元组数组(生成Array((t,this), (h,this), (i,this), ...))。

    • 第二步是将这些字符和单词的元组按字符分组,并将分组的值映射到相关的单词。这可以通过groupMap 来实现(groups 元组由它们的第一部分(按字符)和maps 分组元组到它们的第二部分(单词))。如果您使用的是早期的 Scala 版本(2.13 之前),则必须将 groupMap 替换为 groupBymapValues 的组合:.groupBy(_._1).mapValues(_.map(_._2))

    【讨论】:

    • 我建议使用"\W+" 来分割任何非单词字符。
    【解决方案2】:

    这是另一种解决方案。您可以用解析器替换我建议的粗分词器,例如 Stanford CoreNLP Simple,例如 info here

    def tokenizeText(s:String):Array[String] = {
       s.toLowerCase().split("[\\W]+")
    }
    
    val text:String = "Here you have your text. Set several sentences if you like."
    val words = tokenizeText(text)
    val letters = words.mkString("").toSet.mkString("").split("")
    val twoDArray:Array[Array[String]] = letters.map(l => words.filter(w => w.contains(l)))
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-15
      相关资源
      最近更新 更多