1
votes

I am working on some of the exercism.io exercises. The current one I am working on is for Scala DNA exercise. Here is my code and the errors that I am receiving:

For reference, DNA is instantiated with a strand String. This DNA can call count (which counts the strand for the single nucleotide passed) and nucletideCounts which counts all of the respective occurrences of each nucleotide in the strand and 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

}

The errors I am receiving are:

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 ^

I am quite new to Scala, so any enlightenment on why these errors are occurring and suggestions to fixing them would be greatly appreciated.

4

4 Answers

2
votes

for comprehensions work over Traversable's that have flatMap and map methods defined, as the error message is pointing out.

In your case count returns with a simple integer so no need to "iterate" over it, just simply add it to your result set.

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

On a side note this solution is not too optimal as in the case of a strand AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA count is going to be called many times. I would recommend calling toSet so you get the distinct Chars only:

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

In line with Akos's approach, consider a parallel traversal of a given strand (String),

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

Here we use distinct to gather unique items and construct each Map association in map.

0
votes

A pipeline solution would look like:

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

Another approach is

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

Not sure why it's different than {...}.toMap() but it gets the job done!

Another way to go is

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