使用元组,案例类来更好地抽象数据结构

时间:2015-06-08 16:43:31

标签: scala

我正在阅读以下内容:

0 3
4 6
6 7
3 5
0 7

每行代表一个测试用例(数字代表索引)。

我有另一个与测试用例中的索引匹配的值数组。

val widthValues = List(2, 3, 1, 2, 3, 2, 3, 3)  

所需的结果是根据测试用例中的索引范围从拼接数组中找到最小宽度值。

e.g。测试用例"0 3"返回1作为min List(2, 3, 1, 2)的{​​{1}},widthValues从索引03

我目前有这个

    val widthValues = List(2, 3, 1, 2, 3, 2, 3, 3)
    val in = stdin.getLines
    for(testCase <- in) {  
         val case = testCase.split(" ").map(_.toInt).toList 
         println(widthValues.slice(case(0), case(1)).min)
    }

我宁愿进一步抽象结构,也许使用元组?案例类?将范围表示为(i,j)。像一个元组列表(i,j)??我不确定。

必须有一个更好的方法来做到这一点,我不确定我需要在这里使用什么Scala技巧。

3 个答案:

答案 0 :(得分:2)

这是一种稍微好一点的方法

val Array(idx1,idx2) = testCase.split(" ").map(_.toInt) 
println(widthValues.slice(idx1, idx2).min)

这允许您使用有意义的变量名而不是case(0)

如果您计划进一步存储,我建议使用案例类,例如

case class TestCase( idx1: Int, idx2: Int )

答案 1 :(得分:1)

@eugener向您展示了最短的解决方案(IMO)。如果您想要一个更抽象范围的解决方案(假设您在更大的设置中工作)。考虑使用Scala的Range类:

val Array(lo, hi) = testCase.split(" ").map(_.toInt)
val range = lo to hi
println(widthValues.slice(range.start, range.end).min) 

当然,这只有在传递它时才有用。否则只是直接使用索引可能更好。

答案 2 :(得分:1)

更具伸缩性的方法,

class Interval(a: Int, b: Int) {
  def apply(xs: List[Int]) = xs.slice(a,b)
}

object Interval {
  def apply(s: String) = {
    val Array(a,b) = s.split("\\s+").map(_.toInt)
    new Interval(a,b)
  }
}

使用如下,

val intervals = testcases.map(Interval(_))
val allLeast = intervals.map(_(widthValues).min)