1

I want to analyze a number in the interval,like this,

samle data,x=5

interval,

0 < x <= 10 then 0
10< x <= 20 then 1
20< x <= 30 then 2

the result is 0.

I want to use a simple way to deal with this, I don't want to write if ...else in scala.

lee
  • 159
  • 1
  • 2
  • 7
  • Possible duplicate of [How can I pattern match on a range in Scala?](https://stackoverflow.com/questions/3160888/how-can-i-pattern-match-on-a-range-in-scala) – Harald Gliebe Sep 13 '18 at 06:18
  • If there are many of them use a interval/range map, else use pattern matching. – bobah Sep 13 '18 at 06:50

5 Answers5

2

Pattern matching with if-guards:

x match {
  case _ if x > 0 && x <= 10 => 0
  case _ if x <= 20          => 1
  case _ if x <= 30          => 2
}
Alvaro Carrasco
  • 6,103
  • 16
  • 24
2

If your range of values is not limited, you could use an integer division by 10:

x / 10 // 5/10 = 0   17/10 = 1   21/10 = 2   1234/10 = 123

An integer division is a division which only keeps the the integer part (doesn't keep the decimal part):

5  / 10 = 0 //  5 = 0*10 + 0.5*10
13 / 10 = 1 // 13 = 1*10 + 0.3*10

More specifically, as your interval starts at 10*n+1, you can use:

(x-1) / 10 // 1=>0, 10=>0, 11=>1
Xavier Guihot
  • 54,987
  • 21
  • 291
  • 190
  • 1
    I feel like this should be the expected answer. It scales to arbitrary numbers of ranges and is simple integer arithmetic. Using pattern matching or conditionals for this would be crazy – Hugo Firth Sep 13 '18 at 08:18
0

Not really elegant but can help:

   x match {
      case _ if  0 to 10 contains x => 0
      case _ if 10 to 20 contains x => 2
      case _  => 3
   }
SCouto
  • 7,808
  • 5
  • 32
  • 49
0
val q = 20

val result = q match {
  case _ if 0 to 10 contains q => 0
  case _ if 10 to 20 contains q => 1
  case _ if 20 to 30 contains q => 3
}

'until' wont include the last number in that range so instead use 'to'

talkdatatome
  • 614
  • 1
  • 10
  • 17
0

Forming two vectors with intervals and code values for these intervals may help: ( throws NoSuchElementException if the value supplied in not in any of the intervals provided.).I personally favour this because it will be flexible to add more data ( both intervals and code values for these intervals in stead of adding long list of case statements in code for all the intervals if the value supplied is to be tested against large number of intervals and corresponding code values for these intervals. It will be flexible enough to variable intervals in stead of constant ranges. )

val v1 = Vector((0,10),(10,20),(20,30)); val v2 = Vector(0,1,2)
def getCode(x:Int,ivals:Vector[(Int,Int)],codes:Vector[Int]) ={
 v1.zip(v2).find(t=>t._1._1<x && t._1._2>=x).get._2  }

Usage:

scala> val v1 = Vector((0,10),(10,20),(20,30))
v1: scala.collection.immutable.Vector[(Int, Int)] = Vector((0,10), (10,20), (20,30))

scala> val v2 = Vector(0,1,2)
v2: scala.collection.immutable.Vector[Int] = Vector(0, 1, 2)

scala> getCode(5,v1,v2)
res14: Int = 0

scala> getCode(23,v1,v2)
res15: Int = 2
RAGHHURAAMM
  • 1,099
  • 7
  • 15