Scala 理解错误

Scala Comprehension Errors

我正在做一些 exercism.io 练习。我目前正在研究的是 Scala DNA 练习。这是我的代码和我收到的错误:

作为参考,DNA 是用字符串字符串实例化的。该 DNA 可以调用计数(计算通过的单核苷酸的链数)和核苷计数,计算链中每个核苷酸的所有相应出现次数和 returns a Map[Char,Int].

class DNA(strand:String) {

  def count(nucleotide:Char): Int = {
    strand.count(_ == nucleotide)
  }

  def nucleotideCounts = (
    for {
      n <- strand
      c <- count(n)
    } yield (n, c)
  ).toMap

}

我收到的错误是:

Error:(10, 17) value map is not a member of Int c <- count(n) ^

Error:(12, 5) Cannot prove that Char <:< (T, U). ).toMap ^

Error:(12, 5) not enough arguments for method toMap: (implicit ev: <:<[Char,(T, U)])scala.collection.immutable.Map[T,U]. Unspecified value parameter ev. ).toMap ^

我是 Scala 的新手,因此非常感谢任何关于为什么会出现这些错误的启发以及修复这些错误的建议。

for 理解在定义了 flatMapmap 方法的 Traversable 上工作,正如错误消息所指出的那样。

在你的情况下 count returns 有一个简单的整数,所以不需要 "iterate" 超过它,只需将它添加到你的结果集中。

for {
  n <- strand
} yield (n, count(n))

附带说明一下,这个解决方案不是太理想,因为链 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA count 将被调用多次。我会建议调用 toSet 以便您只获得不同的 Chars:

for {
  n <- strand.toSet
} yield (n, count(n))

管道解决方案如下所示:

def nucleotideCounts() = strand.groupBy(identity).mapValues(_.length)

配合Akos的做法,考虑平行遍历给定的strand(String),

strand.distinct.par.map( n => n -> count(n) )

这里我们使用 distinct 来收集唯一项并在 map 中构建每个 Map 关联。

另一种方法是

Map() ++ {for (n <- strand; c = count(n)) yield n->c}

不确定为什么它与 {...}.toMap() 不同,但它完成了工作!

另一种方法是

Map() ++ {for (n <- strand; c <- Seq(count(n))) yield n->c}