我有一个包含纯文本的文件,如下所示:
“Umbrella!!
This is a very red umbrella.
The umbrella should not be this red.
”
我从中提取所有关键字(将所有单词转换为小写后)并按字母顺序排序,这给了我:
keywords = List(red, umbrella)
现在,我想逐行阅读文件,找到包含单词“red”和“umbrella”的行号,即关键字列表中的单词。
我知道如何逐行阅读文件:
for(line <- Source.fromFile("file.txt").getLines())
但是,如何解析行中的每个单词并将其与list元素进行比较?请帮忙!!
编辑:
我希望输出如下:
red 2 3
umbrella 1 2 3
1 2 3是行号。
答案 0 :(得分:2)
在每一行上使用keywords.exists(line.contains)
并在需要时打印索引
Source.fromFile("file.txt").getLines().zipWithIndex.foreach {
case(line, index) =>
if (keywords.exists(line.contains)) println(index)
}
如果您希望它不具备个案意义,请执行line.toLowerCase.contains
Source.fromFile("file.txt").getLines().zipWithIndex.foreach {
case(line, index) =>
if (keywords.exists(line.toLowerCase.contains)) println(index)
}
更新(以反映答案中的变化)
使输出类似于
red 2 3
umbrella 1 2 3
让我们创建一个存储每个单词的行号的地图。
var count = scala.collection.mutable.Map[String, List[Int]]()
keywords.foreach { k => count += k -> List[Int]()}
Source.fromFile("file.txt").getLines().zipWithIndex.foreach {
case (line, index) =>
keywords.foreach { w =>
if (line.toLowerCase.contains(w))
count(w) = count(w) :+ (index + 1)
}
}
count.keys.foreach{ i => println(i + " " + count(i) )}
要使输出完全符合您的指定,请将最后一行替换为
count.keys.foreach{ i =>
print(i + " ")
count(i).foreach{ j => print(j + " ") }
println()
}
答案 1 :(得分:0)
您可以将每一行拆分为单词,然后检查该列表是否包含所有关键字。使用zipWithIndex获取行号:
Source.fromFile("file.txt").getLines().zipWithIndex.filter { case(line, index) =>
val words = line.toLowerCase.split("\W")
keywords.forall(words.contains)
}
.map(_._2)
编辑:如果你想为每个keywrod分别建立索引,你首先需要将flatMap放入(word,index)元组列表中,然后再分组:
Source.fromFile("file.txt").getLines().zipWithIndex
.flatMap { case(line, index) =>
line.toLowerCase.split("\W").map { (_, index+1) } // "+1 because indexes are 0-based
}
.filter { keywords.contains(_._1) }
.groupBy { _._1 }.mapValues(_._2)
这为您提供了Map [String,List [Int]],其中键是关键字,值是给定关键字出现的行的索引列表。