scala-在保留顺序的情况下获取列表中单词的运行计数

scala-在保留顺序的情况下获取列表中单词的运行计数,scala,Scala,我试图通过保持元素的顺序来获得列表中单词的运行计数 scala> val a = List("she","sells","seashells","by","the","seashore","the", "shells", "she", "sells", "are", "surely", "seashells","where", "are", "the", "shells") a: List[String] = List(she, sells, seashells, by, the, sea

我试图通过保持元素的顺序来获得列表中单词的运行计数

scala> val a = List("she","sells","seashells","by","the","seashore","the", "shells", "she", "sells", "are", "surely", "seashells","where", "are", "the", "shells")
a: List[String] = List(she, sells, seashells, by, the, seashore, the, shells, she, sells, are, surely, seashells, where, are, the, shells)

scala> a.map( x => (x,a.count(_ == x)))
res13: List[(String, Int)] = List((she,2), (sells,2), (seashells,2), (by,1), (the,3), (seashore,1), (the,3), (shells,2), (she,2), (sells,2), (are,2), (surely,1), (seashells,2), (where,1), (are,2), (the,3), (shells,2))

scala>
但我想要的是

List((she,1), (sells,1), (seashells,1), (by,1), (the,1), (seashore,1), (the,2), (shells,1), (she,2), (sells,2), (are,1), (surely,1), (seashells,2), (where,1), (are,2), (the,3), (shells,2))
尝试了下面这样的操作,但出现了抛出错误

scala> a.scanLeft(scala.collection.mutable.Map[String,Int]()){ (x,t) => {x(t) = x(t)+1; (x) } }
java.util.NoSuchElementException: key not found: she
  at scala.collection.MapLike$class.default(MapLike.scala:228)
  at scala.collection.AbstractMap.default(Map.scala:59)
  at scala.collection.mutable.HashMap.apply(HashMap.scala:65)
  at $anonfun$1.apply(<console>:13)
  at $anonfun$1.apply(<console>:13)
  at scala.collection.TraversableLike$$anonfun$scanLeft$1.apply(TraversableLike.scala:374)
  at scala.collection.TraversableLike$$anonfun$scanLeft$1.apply(TraversableLike.scala:374)
  at scala.collection.immutable.List.foreach(List.scala:381)
  at scala.collection.TraversableLike$class.scanLeft(TraversableLike.scala:374)
  at scala.collection.AbstractTraversable.scanLeft(Traversable.scala:104)
  ... 32 elided

scala>
scala>a.scanlight(scala.collection.mutable.Map[String,Int]()){(x,t)=>{x(t)=x(t)+1;(x)}
java.util.NoSuchElementException:未找到密钥:she
位于scala.collection.MapLike$class.default(MapLike.scala:228)
位于scala.collection.AbstractMap.default(Map.scala:59)
位于scala.collection.mutable.HashMap.apply(HashMap.scala:65)
在$anonfun$1.应用(:13)
在$anonfun$1.应用(:13)
在scala.collection.TraversableLike$$anonfun$scanleet$1.apply处(TraversableLike.scala:374)
在scala.collection.TraversableLike$$anonfun$scanleet$1.apply处(TraversableLike.scala:374)
位于scala.collection.immutable.List.foreach(List.scala:381)
位于scala.collection.TraversableLike$class.scanlight(TraversableLike.scala:374)
位于scala.collection.AbstractTraversable.Scanlight(Traversable.scala:104)
... 32删去
斯卡拉>

一个相当复杂的
foldLeft
似乎可以工作

a.foldLeft((List.empty[(String,Int)],Map[String,Int]().withDefaultValue(0))){
  case ((lst,cnts),s) => ((s,cnts(s)+1) :: lst, cnts + ((s,cnts(s)+1)))
}._1.reverse
//res0: List[(String, Int)] = List((she,1), (sells,1), (seashells,1), (by,1), (the,1), (seashore,1), (the,2), (shells,1), (she,2), (sells,2), (are,1), (surely,1), (seashells,2), (where,1), (are,2), (the,3), (shells,2))

以下是使用与原始代码相同原则的版本:

a.reverse.tails.collect{case s :: t => (s, t.count(_ == s) + 1)}.toList.reverse
但这对于长列表来说是缓慢且低效的,所以我会使用前面的答案

最有效的解决方案是使用可变的
Map
ListBuffer
,但在这种情况下,这似乎有些过分:

def wordCount(s: List[String]): List[(String, Int)] = {
  val wordMap = collection.mutable.Map.empty[String, Int].withDefaultValue(0)
  val res = collection.mutable.ListBuffer.empty[(String, Int)]

  s.foreach{ s =>
    wordMap(s) += 1
    res += s -> wordMap(s)
  }

  res.toList
}

试试FoldLeft操作吧?谢谢。。。我尝试在foldLeft中传递Map后跟List..这是一个抛出错误..
a.foldLeft((Map[String,Int]()。withDefaultValue(0),List.empty[(String,Int)]){((m,lst),s)=>m+(s,m(s)+1),(s,m(s)+1::lst}.\u 2.反向
。您能帮助修复这个问题吗?四个错误:1-在花括号之前缺少关闭参数
{
.2-花括号后缺少
大小写
关键字
{
.3-结果元组周围需要参数,否则它不是元组。4-需要另一个参数集
()
来生成添加到
映射的元组:
m+((s,m(s)+1))
。如果不这样做,看起来您试图将两个参数传递给
+()
方法,这显然是不正确的。是的。最后,这起作用了。
a.foldLeft((Map[String,Int]()。withDefaultValue(0),List.empty[(String,Int)]{case((m,lst),s=>(m+((s,m(s)+1)),(s,m(s)+1)::lst}.u 2.reverse
a.scanLeft(scala.collection.mutable.Map[String,Int]()。withDefaultValue(0)){(x,t)=>((t,x(t)+1))
不起作用的原因是什么?.zero元素是一个
Map[String,Int]
,因此
(x,t)=>
计算的结果需要是一个
Map[String,Int]
因为每次计算的结果都会传递给下一次迭代。要获得正确的类型,一个简单的mod应该是
=>x+((t,x(t)+1))
,但它不会得到你想要的结果。我认为这不能用
扫描来完成。你能特别尝试一下吗,我想在一个答案中避免可变变量c