#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)
}
}