Ben Che
Ben Che

Reputation: 79

Using tuples, case classes to better abstract a data structure

I'm reading the following input:

0 3
4 6
6 7
3 5
0 7

Each row represents a test case (numbers represent indices).

I have another array of values that match to the indices in the test case.

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

The desired result is finding the minimum width value from a spliced array based on the index range in the test case.

e.g. test case "0 3" returns 1 as the min of List(2, 3, 1, 2) which is widthValues from index 0 to 3.

I currently have this

    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'd rather abstract the structure a little further though, maybe using tuples? case classes? to represent the range as (i, j). like a list of tuples(i, j)?? I'm not sure.

There's got to be a better way of doing this, and I'm not sure what Scala tricks I need to use here.

Upvotes: 2

Views: 112

Answers (3)

elm
elm

Reputation: 20415

A more scalable approach,

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)
  }
}

Use it as follows,

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

Upvotes: 1

Eugene Ryzhikov
Eugene Ryzhikov

Reputation: 17359

Here is a slightly better way

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

This allows you to use meaningful variable names instead of case(0)

If you plan to store those further, I would suggest using case class, such as

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

Upvotes: 2

gzm0
gzm0

Reputation: 14842

@eugener has shown you the shortest solution (IMO). If you would like a solution that abstracts the range more (assuming you work in a larger setting). Consider using Scala's Range class:

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

Of course, this is only useful if you pass it around. Otherwise just using the indices directly is probably better.

Upvotes: 1

Related Questions