Вычислите количество вхождений букв и поместите словари в список

#scala

#scala

Вопрос:

Я пытаюсь подсчитать вхождения букв в потоке строк, а затем поместить карты для каждой строки («буква»-> количество) в список.

 def checksum(ipt: Stream[String]) =  ipt.foldLeft(List(Map("x"->1)))( (n: 
List[Map[String, Int]], m: String)  => n    
m.split("").groupBy(identity).mapValues(_.size).toMap)
  

Это создает проблему:

  Expression of type List[Equals] doesn't conform to expected type List[Map[String, Int]]
  

Что не так? Вроде бы нет проблем с выполнением этого для каждой строки:

  def checksum(ipt: Stream[String]) =  ipt.foreach( (m: String)  => println(m.split("").groupBy(identity).mapValues(_.size)))
  

Это дает что-то вроде этого на

 val s = "bababc"
val d = "abbcde"
checksum(List(s,d).toStream)
out: 
Map(b -> 3, a -> 2, c -> 1)
Map(e -> 1, a -> 1, b -> 2, c -> 1, d -> 1)
  

Но как мне теперь поместить все эти карты в список? Я не могу использовать переменные и должен сделать это в одном выражении.

Ответ №1:

если вам нужна карта для каждой строки, вы можете добиться этого с помощью функции map над первым потоком следующим образом:

  def checksums(ipt: Stream[String]): Stream[Map[Char, Int]] = {
    ipt.map(checksum)
 }

 def checksum(ipt: String): Map[Char, Int] = ipt.foldLeft(Map.empty[Char, Int]) { case (acc, ch) =>
     acc.get(ch) match {
        case Some(q) => acc   (ch -> (q   1))
        case None => acc   (ch -> 1)
     }
 }
  

Возвращаясь к вашему коду, оператор для добавления элемента в список: , а не .

используется для объединения списков.

Итак, вы можете исправить свой код следующим образом:

 def checksumFixed(ipt: Stream[String]) = {
    ipt.foldLeft(List(Map("x"->1))) { (n: List[Map[String, Int]], m: String) =>
      n :  m.split("").groupBy(identity).mapValues(_.length)
    }
  }