【问题标题】:How To Create a Map of Vowel Combinations from Words in a Text File如何从文本文件中的单词创建元音组合图
【发布时间】:2018-04-29 11:36:47
【问题描述】:

我需要使用 Scala 聚合文本文件中单词的元音组合。例如,如果文本文件是: “这是一个文本文件。”

输出将类似于 (i,2) (a,1) (e,1) (ei,1)

我是 spark/scala 的新手,所以请原谅我的无知。

我当前的代码:

val wordsFile = sc.textFile("test.txt");
val flattenMap = wordsFile.flatMap(line => line.split(" "))

我制作了一个小元音函数来检查每个字符,但我不确定如何正确实现它。

def isVowel(letter: Char): Boolean = {
letter match {
case 'a' => true;
case 'e' => true;
case 'i' => true;
case 'o' => true;
case 'u' => true;
case _ => false;
}

如何遍历 flattenMap 中的每个单词并将元音存储在新地图中? 谢谢。

【问题讨论】:

  • 你能解释一下输出 (ei,1) 吗?
  • 最后一个单词“file”包含元音'e'和'i'。
  • 那么你也可以说它包含(即1)不是吗?如果它回答了您的问题,请在下面查看我的回答
  • 我可以看到元音需要按字母顺序而不是单词中的顺序,但是你能澄清一下如果单词中有两个相同的元音会发生什么吗? “the”和“there”有相同的“元音组合”还是一个“e”和另一个“ee”?

标签: scala apache-spark


【解决方案1】:

如何从文本文件中的单词创建元音组合图

您需要做的就是用空格替换辅音,然后您将剩下元音组合,然后只需使用reduceByKey 计数 他们。

val wordsFile = sc.textFile("test.txt")
val flattenMap = wordsFile
                    .flatMap(line => line.toLowerCase.replaceAll("[bcdfghjklmnpqrstvwxyz]", " ").split(" "))
                    .filter(_ != "")
                    .map((_, 1))
                    .reduceByKey(_ + _)

注意:该解决方案会计算整个文本中元音的确切组合,因此您可以根据组合要求进行修改

所以如果你输入为

This is a text file teefie

输出将是

(ee,1)
(e,2)
(a,1)
(i,3)
(ie,1)

更新

查看您的预期输出为

输出类似于 (i,2) (a,1) (e,1) (ei,1)

下面的修改应该会给出结果

val wordsFile = sc.textFile("test.txt")
val flattenMap = wordsFile.flatMap(line => line.split(" ").map(_.toLowerCase.replaceAll("[bcdfghjklmnpqrstvwxyz.,]", "").sorted))
                    .filter(_ != "")
                    .map((_, 1))
                    .reduceByKey(_ + _)

这应该为您提供输入This is a text file.的以下输出

(e,1)
(a,1)
(i,2)
(ei,1)

【讨论】:

  • 谢谢拉梅什!
【解决方案2】:

这是一个使用groupBy 的解决方案,它根据从每个数据值计算出的键对数据进行分组。

val text = "This is a text file."

def vowels(s: String) = s.replaceAll("[^aeiou ]", "").sorted

text
  .trim.split("\\s+")
  .groupBy(vowels)
  .collect{ case(k, v) => (k, v.length) }

vowels 函数从单词中提取元音。此版本对元音进行排序,但不组合同一元音的多个实例。将其替换为您想要的确切操作。这可以是从单词中提取重要特征的任何函数。

trim 和 split 将文本分成由空格分隔的单词。

groupBy根据@​​987654327@的结果对单词进行分组。

collect 将groupBy 生成的列表转换为计数。

结果是Map[String, Int],但如果您需要List 而不是Map,请使用toList。

更新以处理大写元音

如果您需要处理大写元音,有三种可能的路线。

1) 在开头转换字符串

.trim.toLowerCase.split("\\s+")

这可能更有效,但将有关元音大小写的规则放在vowels 检查中可能更合乎逻辑

2) 转换vowels中的字符串

def vowels(s: String) = s.toLowerCase.replaceAll("[^aeiou ]", "").sorted

3) 将大写元音添加到模式中

def vowels(s: String) = s.replaceAll("[^AaEeIiOoUu ]", "").sorted

这保留了元音的大小写,这可能是也可能不是想要的。

【讨论】:

    猜你喜欢
    • 2011-10-05
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-12
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    相关资源
    最近更新 更多