Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
scala-在求和结束时获取总计_Scala - Fatal编程技术网

scala-在求和结束时获取总计

scala-在求和结束时获取总计,scala,Scala,我有一个列表,我需要得到频率操作的总计数,作为结果末尾的附加元素 scala> val a = List("decimal","string","string","decimal","timestamp","decimal", "timestamp" ) a: List[String] = List(decimal, string, string, decimal, timestamp, decimal, timestamp) scala> a.foldLeft(Map[Strin

我有一个列表,我需要得到频率操作的总计数,作为结果末尾的附加元素

scala> val a = List("decimal","string","string","decimal","timestamp","decimal", "timestamp" )
a: List[String] = List(decimal, string, string, decimal, timestamp, decimal, timestamp)

scala> a.foldLeft(Map[String,Int]().withDefaultValue(0)){ case (acc,x) =>  acc+(x->(acc(x)+1))  }
res103: scala.collection.immutable.Map[String,Int] = Map(decimal -> 3, string -> 2, timestamp -> 2)
我需要的是

Map(decimal -> 3, string -> 2, timestamp -> 2, total -> 7)
我能用下面的代码得到

Map("total" -> a.size) ++ a.foldLeft(Map[String,Int]().withDefaultValue(0)){ case (acc,x) =>  acc+(x->(acc(x)+1))  }
但是如何使用
a.foldLeft(Map(“total”->0))
实现。我正在尝试下面的方法,但出现了错误

scala> a.foldLeft( Map("total" -> 0 ) ){ case (acc,x) =>  acc+(x->(acc(x)+1))  }
java.util.NoSuchElementException: key not found: decimal
  at scala.collection.MapLike$class.default(MapLike.scala:228)
  at scala.collection.AbstractMap.default(Map.scala:59)
  at scala.collection.MapLike$class.apply(MapLike.scala:141)
  at scala.collection.AbstractMap.apply(Map.scala:59)

我认为这会起作用:

val a = List("decimal","string","string","decimal","timestamp","decimal", "timestamp" )
a.foldLeft(Map("total" -> 0).withDefaultValue(0)) (
  (acc,x) =>
    acc.updated(x,acc(x) + 1)
       .updated("total",acc("total") + 1)
)
编辑:我正在考虑:

  • @jwvh的第一条注释是使用operator
    +
    而不是为了简洁而更新的
  • @jwvh的第二个注释是删除
    “total”->0,这显然是不必要的
  • 重构两个键的递增值
解决方案变成:

def incrementValOfKeys(acc: Map[String, Int], keys: String*) = keys.foldLeft(acc)(
  (acc, key) => acc + (key -> (acc(key) + 1))
)

val a = List("decimal","string","string","decimal","timestamp","decimal", "timestamp" )
a.foldLeft(Map[String,Int]().withDefaultValue(0)) (incrementValOfKeys(_, _, "total"))
如果您想玩它:

incrementValOfKeys
为调用
acc的
映射[String,Int]
增加
keys
给定的每个键的值

其思想是在
foldLeft
中以迭代方式完成调用: incrementValOfKeys(映射当前状态、当前键、“总计”)

下面是一些
incrementalofkeys
的示例,它对应于使用您在问题中给出的主
foldLeft
计算
a
的迭代步骤:

  • incrementValOfKeys(映射[String,Int]()。带默认值(0),“decimal”,“total”)
    给出
    Map(“十进制”->1,“总计”->1)
  • incrementValOfKeys(Map[String,Int](“decimal”->1,“total”->1)。使用defaultvalue(0),“String”,“total”)
    给出
    Map(“decimal”->1,“total”->2,“String”->1)
  • incrementvalof键(映射[String,Int](“十进制”->1,“总计”->2,“字符串”->1)。使用默认值(0),“字符串”,“总计”)
    给出
    Map(“十进制”->1,“总计”->3,“字符串”->2)
  • 等等

如果使用
case(acc,x)=>acc+(x->(acc(x)+1)+(“total”->(acc(“total”)+1)),
而不是调用它,则不必使用
incrementValOfKeys
如果使用
case(acc,x)=>acc+(“total”->(acc(“total”)+1))
而不必调用它。

在构建
映射时不需要累计总数,您只需使用输入的
大小:

a.groupBy(identity).map{case (k, v) => k -> v.size} + ("total" -> a.size)
注意

2.13中的集合库有一个新的
groupMapReduce
方法,该方法将使此过程更简单、更高效,如下所示:

a.groupMapReduce(identity)(_ => 1)(_+_) + ("total" -> a.size)

=>acc+(x->(acc(x)+1)+(“总计”->(acc(“总计”)+1))
@jwvh。。不,这也是一个错误。我用你第一次发布的代码测试了它<代码>映射(“总计”->0)
不需要。@jwvh。。是的,你是对的,它是有效的。。这很有效。。需要再次使用DefaultValue(0)给出什么?您的种子在开始时没有其他键,只有
“total”
。因此,您希望更新在遇到新键时不会失败,例如
“decimal”
。尝试不使用
。使用默认值(0)
并将
a
设置为
List(“十进制”)
。我希望它会失败,而且是不言自明的。是的。。但是我们已经有了
Map(“total”->0)
,它的默认权限是0?是的,但是它只适用于
“total”
,不适用于其他键。这就是为什么一开始没有值的
“decimal”
会抛出一个异常,因为在休闲地图上,如果之前没有插入键,你就不能毫无例外地调用
acc(x)
。我编辑了以前的解决方案,删除了
“total”->0
@stack0114106,并提供了一个链接来摆弄它。我希望这能让你更好地理解,如果情况还不是这样的话。