如何在Scala中将list元素的值赋值为缓冲区列表的新元素?

时间:2016-05-24 15:58:14

标签: arrays list scala

我正在尝试计算每个“DayOfWeek”的“ViewTime”的总和和平均值,以及每个“id”的每个“DayOfWeek”。作为一个例子,我试图在DayOfWeek ==“Monday”时这样做。我试图创建一个id列表和一个ViewTime列表,但我遇到了以下错误。什么是最好的解决方案?

case class ds(DayOfWeek : String, id: String, ViewTime: Long)

val datasample = Array(ds("Monday", "h100", 20).productIterator.toList,  ds("Tuesday", "h200", 30).productIterator.toList, ds("Monday", "h400", 10).productIterator.toList, ds("Sunday", "h100", 4).productIterator.toList, ds("Tuesday", "h300", 5).productIterator.toList, ds("Sunday", "h200", 0).productIterator.toList, ds("Tuesday", "h100", 1).productIterator.toList, ds("Tuesday", "h400", 50).productIterator.toList)

var bufInt = scala.collection.mutable.ListBuffer.empty[Int]
var bufString = scala.collection.mutable.ListBuffer.empty[String]

val y = datasample.length
var x = ds("Tuesday", "h200", 30).productIterator.toList

var j = 0 
var s = 0

while (j <= y-1) {
  x =  datasample(j) 
  if ( x(0) == "Monday") {
      bufInt += x(2)
      bufString += x(1)
      s += 1
}
j += 1
}
println(bufInt)
println(bufString)

错误

<console>:61: error: type mismatch;
 found   : Any
 required: Int
                    bufInt += x(2)
                               ^
<console>:62: error: type mismatch;
 found   : Any
 required: String
                    bufString += x(1)
                                  ^

2 个答案:

答案 0 :(得分:1)

在回答你的问题之前,我想我应该谈谈列表元组

之间的区别

列表必须包含相同类型的值,而元组可以包含不同类型的元素。出于这个原因,

ds("Tuesday", "h200", 30).productIterator.toList

将生成一个

列表
List(Tuesday, h200, 30)

第一个元素是星期二,第二个元素是 h200 ,第三个元素是 30 。但这些元素的类型是什么?众所周知,列表必须包含相同类型的元素,显然列表(星期二,h200,30)的类型不是字符串,并且也不是 Int

字符串 Int 的类型从任意的类型扩展而来。所以我们可以说 List(星期二,h200,30)包含类型为 Any

的元素

bufInt 的“+ =”需要类型为 Int 的运算符,而 bufString 需要字符串,两者都不是任何。所以错误出现了。

只需按照以下

修改您的代码即可
case class ds(DayOfWeek : String, id: String, ViewTime: Long)

val datasample = Array(ds("Monday", "h100", 20),  ds("Tuesday", "h200", 30), ds("Monday", "h400", 10), ds("Sunday", "h100", 4), ds("Tuesday", "h300", 5), ds("Sunday", "h200", 0), ds("Tuesday", "h100", 1), ds("Tuesday", "h400", 50))

var bufInt = scala.collection.mutable.ListBuffer.empty[Int]
var bufString = scala.collection.mutable.ListBuffer.empty[String]

val y = datasample.length
var x = ds("Tuesday", "h200", 30)

var j = 0
var s = 0

while (j <= y-1) {
  x = datasample(j)
  if ( x.DayOfWeek == "Monday") {
    bufInt += x.id.toInt
    bufString += x.id
    s += 1
  }
  j += 1
}
println(bufInt)
println(bufString)
}
祝你好运

答案 1 :(得分:0)

首先,做一些你想做的事情略微扭曲:

case class ds(DayOfWeek : String, id: String, ViewTime: Long)

val datasample = Array(ds("Monday", "h100", 20),
                       ds("Tuesday", "h200", 30),
                       ds("Monday", "h400", 10),
                       ds("Sunday", "h100", 4),
                       ds("Tuesday", "h300", 5),
                       ds("Sunday", "h200", 0),
                       ds("Tuesday", "h100", 1),
                       ds("Tuesday", "h400", 50)) 

// changed Int to Long here to match the case class

val bufInt = scala.collection.mutable.ListBuffer.empty[Long]
val bufString = scala.collection.mutable.ListBuffer.empty[String]

for (sample <- datasample
     if  sample.DayOfWeek == "Monday") {
       bufInt += sample.ViewTime
       bufString += sample.id
}
println(bufInt)                                   //> ListBuffer(20, 10)
println(bufString)                                //> ListBuffer(h100, h400)

然后更惯用的方式:

datasample.collect{case ds(day, id, _) if day == "Monday" => id}
//> res0: Array[String] = Array(h100, h400)
datasample.collect{case ds(day, _, time) if day == "Monday" => time}
//> res1: Array[Long] = Array(20, 10)

或者如果您更喜欢for理解:

for (sample <- datasample
     if  sample.DayOfWeek == "Monday") yield sample.ViewTime
                                              //> res2: Array[Long] = Array(20, 10)

for (sample <- datasample
     if  sample.DayOfWeek == "Monday") yield sample.id
                                              //> res3: Array[String] = Array(h100, h400)

案例类等的全部意义在于提供一种将事物收集到一个结构中的便捷方式。用productIterator将它们打包到一个列表中只是奇怪的,我不知道你为什么要从这条路线开始。