映射减少字符串中的总和项目权重
map reduce sum item weights in a string
我有如下字符串:
s = "eggs 103.24,eggs 345.22,milk 231.25,widgets 123.11,milk 14.2"
这样一对item和它对应的weight用逗号隔开,item name和它的weight用space隔开。我想得到每个项目的重量总和:
//scala.collection.immutable.Map[String,Double] = Map(eggs -> 448.46, milk -> 245.45, widgets -> 123.11)
我已经完成了以下操作,但在分离物品及其重量的步骤上卡住了:
s.split(",").map(w=>(w,1)).sortWith(_._1 < _._1)
//Array[(String, Int)] = Array((eggs 345.22,1), (milk 14.2,1), (milk 231.25,1), (widgets 103.24,1), (widgets 123.11,1))
我想继续,对于数组中的每个元素,我需要分离出由 space 分隔的项目名称和权重,但是当我尝试以下操作时,我感到很困惑:
s.split(",").map(w=>(w,1)).sortWith(_._1 < _._1).map(w => w._1.split(" ") )
//Array[Array[String]] = Array(Array(eggs, 345.22), Array(milk, 14.2), Array(milk, 231.25), Array(widgets, 103.24), Array(widgets, 123.11))
我不确定下一步应该如何进行计算。
如果您保证字符串采用这种格式(因此没有异常和边缘情况处理),您可以这样做:
val s = "eggs 103.24,eggs 345.22,milk 231.25,widgets 123.11,milk 14.2"
val result = s
.split(",") // array of strings like "eggs 103.24"
.map(_.split(" ")) // sequence of arrays like ["egg", "103.24"]
.map { case Array(x, y) => (x, y.toFloat)} // convert to tuples (key, number)
.groupBy(_._1) // group by key
.map(t => (t._1, t._2.map(_._2).sum)) // process groups, results in Map(eggs -> 448.46, ...)
与@GuruStron 提出的类似,但处理可能的错误(通过忽略任何类型的格式错误的数据)。
此外,此版本需要 Scala 2.13+,旧版本将无法运行。
def mapReduce(data: String): Map[String, Double] =
data
.split(',')
.iterator
.map(_.split(' '))
.collect {
case Array(key, value) =>
key.trim.toLowerCase -> value.toDoubleOption.getOrElse(default = 0)
}.toList
.groupMapReduce(_._1)(_._2)(_ + _)
我有如下字符串:
s = "eggs 103.24,eggs 345.22,milk 231.25,widgets 123.11,milk 14.2"
这样一对item和它对应的weight用逗号隔开,item name和它的weight用space隔开。我想得到每个项目的重量总和:
//scala.collection.immutable.Map[String,Double] = Map(eggs -> 448.46, milk -> 245.45, widgets -> 123.11)
我已经完成了以下操作,但在分离物品及其重量的步骤上卡住了:
s.split(",").map(w=>(w,1)).sortWith(_._1 < _._1)
//Array[(String, Int)] = Array((eggs 345.22,1), (milk 14.2,1), (milk 231.25,1), (widgets 103.24,1), (widgets 123.11,1))
我想继续,对于数组中的每个元素,我需要分离出由 space 分隔的项目名称和权重,但是当我尝试以下操作时,我感到很困惑:
s.split(",").map(w=>(w,1)).sortWith(_._1 < _._1).map(w => w._1.split(" ") )
//Array[Array[String]] = Array(Array(eggs, 345.22), Array(milk, 14.2), Array(milk, 231.25), Array(widgets, 103.24), Array(widgets, 123.11))
我不确定下一步应该如何进行计算。
如果您保证字符串采用这种格式(因此没有异常和边缘情况处理),您可以这样做:
val s = "eggs 103.24,eggs 345.22,milk 231.25,widgets 123.11,milk 14.2"
val result = s
.split(",") // array of strings like "eggs 103.24"
.map(_.split(" ")) // sequence of arrays like ["egg", "103.24"]
.map { case Array(x, y) => (x, y.toFloat)} // convert to tuples (key, number)
.groupBy(_._1) // group by key
.map(t => (t._1, t._2.map(_._2).sum)) // process groups, results in Map(eggs -> 448.46, ...)
与@GuruStron 提出的类似,但处理可能的错误(通过忽略任何类型的格式错误的数据)。
此外,此版本需要 Scala 2.13+,旧版本将无法运行。
def mapReduce(data: String): Map[String, Double] =
data
.split(',')
.iterator
.map(_.split(' '))
.collect {
case Array(key, value) =>
key.trim.toLowerCase -> value.toDoubleOption.getOrElse(default = 0)
}.toList
.groupMapReduce(_._1)(_._2)(_ + _)