n grams scala输出集转换

n grams scala output set transformation

def ngrams(n: Int, words: Array[String]) = {
// exclude 1-grams
(1 to n).map { i => words.sliding(i).toStream }
  .foldLeft(Stream[Array[String]]()) {
    (a, b) => a #::: b
  } }   
scala> val op2 =  ngrams(3, "how are you".split(" ")).foreach { x => println((x.mkString(" ")))}  
Output as :    
how
are
you
how are
are you
how are you
op2: Unit = ()

如何避免上面的 Unit 值,实际上我想将它们转换为 Set,因为 Unit=(),它失败了。所以请你帮忙输出应该是 Set(how,are,you,how are,are you,how are you) 感谢 post -- How to generate n-grams in scala?.

这是 op2 的类型签名。你可以做

  1. 删除对 Op2 的分配

ngrams(3, "how are you".split(" ")).foreach { x => println((x.mkString(" ")))}

  1. .foreach 更改为 .map 并为结果调用 op2

scala> val op2 = ngrams(3, "how are you".split(" ")).map { x => x.mkString(" ")}.toList

scala> op2

简短的回答是 foreach 的 return 类型是 Unit。所以当你把foreach的输出赋值给op2时,op2的类型是Unit,它的值是().

听起来你想做的是:

  1. 使用 ngrams 方法计算 n-gram,
  2. 将 n-gram 的 Set 存储到 op2,并且
  3. 打印出所有的 n-grams。

让我们从ngrams方法的类型开始:

(n: Int, words: Array[String]) => Stream[Array[String]]

它 return 是一个 Stream,看起来它可以很容易地变成 SettoSet:

ngrams(3, "how are you".split(" ")).toSet

然而,这很危险,因为在 scala 中,Array 相等是通过引用完成的。将您的 Stream[Array[String]] 变成 Stream[List[String]] 会更安全,这样可以删除任何重复项(假设每个 ngram 中的顺序都很重要):

val op2 = ngrams(3, "how are you".split(" ")).map(_.toList).toSet

现在,可以像打印 Stream[Array[String]] 一样轻松地打印出 Set[List[String]]:

op2.foreach { x => println((x.mkString(" ")))}

因为结果是()Unit类型,没有理由赋值给变量