Scala 字符串中唯一字符的计数
我需要编写一个函数,在给定一个输入Scala 字符串中唯一字符的计数,scala,Scala,我需要编写一个函数,在给定一个输入字符串的情况下,返回(Char,Int)对的列表 我的解决方案产生了正确的结果,但我想知道是否有更好的方法: def countChars(s: String): List[(Char, Int)] = { s.groupBy(c => c.toLower).flatMap(e => List((e._1, e._2.length))).toList }
字符串的情况下,返回(Char,Int)
对的列表
我的解决方案产生了正确的结果,但我想知道是否有更好的方法:
def countChars(s: String): List[(Char, Int)] = {
s.groupBy(c => c.toLower).flatMap(e => List((e._1, e._2.length))).toList
}
这会在工作表中产生如下结果:
countChars("Green Grass")
// res0: List[(Char, Int)] = List(('e', 2), ('s', 2), ('n', 1), ('a', 1), (' ', 1), ('g', 2), ('r', 2))
制作一个单例列表只是为了将其展平是多余的
"Green Grass".groupBy(c => c.toLower).map(e => (e._1, e._2.length)).toList
如果您正在处理长字符串或字符流,那么您的方法将不必要地使用太多内存-在调用flatMap
之前,您基本上是在存储输入字符串中的所有字母。相反,您可以只存储每个字母的出现次数:
import scala.collection.immutable.Map
"Green Grass".map(_.toLower).foldLeft(Map.empty[Char, Int]) { (m, char) =>
val count = m.getOrElse(char, 0)
m.updated(char, count+1)
}.toList
这将返回与您的解决方案相同的结果。稍微美化一下的@dhg asnwer版本:
"Green Grass".groupBy(c => c.toLower).mapValues(group => group.length).toList
你也可以试试这个
def countChars(s: String) =
s.distinct.map(c => c -> s.count(_ == c))
从Scala 2.13
开始,我们可以使用该方法,它是groupBy
/mapValues
的一种一次性替代方法:
"Green Grass".groupMapReduce(_.toLower)(_ => 1)(_ + _).toList
// List[(Char, Int)](('e', 2), ('s', 2), ('n', 1), ('a', 1), (' ', 1), ('g', 2), ('r', 2))
这:
按小写版本对字符进行分组(.toLower
)(分组部分为组MapReduce)
映射
s每个分组值出现1(\u=>1
)(映射组的一部分映射减少)
reduce
s一组值(\uu+\uu
)中的值,方法是将它们相加(reduce-part-of-groupMapreduce)
- 使用
.toList
将生成的映射[Char,Int]
转换为列表[(Char,Int)]
groupMapeduce
阶段是一个可以通过以下方式进行翻译的阶段:
"Green Grass".groupBy(_.toLower).mapValues(_.map(_ => 1).reduce(_+_))
说得好。出于某种原因,我认为我必须使用平面图,所以为了使它能够正常工作,我必须为每个结果列出清单。@nietaki的答案看起来也很有趣。这将线性运算转化为二次运算,对每个c
遍历s
。仅供参考:您不需要导入不可变。Map
。它总是由Predef
自动加载,我知道,我只是想指出我使用的映射:)