sparkr sparkr - 1 month ago 10
Scala Question

Scala find an Int between a List of Int

I have an Int and I need to find in a List of Ints the upper and lower bounds for this Int.

For example:

In a List(1,3,6,9), when I ask for 2, I should get 1 and 3. Is there any pre-built function in the Scala collection API that I can use? I know that I can achieve this using the filter function, but I'm looking for an already existing API if any?

Answer Source

So, not built in, but here you go. Since you want return nothing for (e.g.) 0 and 10, we need to return an option.

var rs = List(1, 3, 6, 9) //> rs  : List[Int] = List(1, 3, 6, 9)
def bracket(n: Int, rs: List[Int]) = {
  val (l, r) = rs.span(_ < n)
  if (l == Nil || r == Nil)
    None
  else if (r.head == n)
    Some((n, n))
  else
    Some((l.last, r.head))
}

bracket(0, rs) //> res0: Option[(Int, Int)] = None
bracket(2, rs) //> res1: Option[(Int, Int)] = Some((1,3))
bracket(6, rs) //> res2: Option[(Int, Int)] = Some((6,6))
bracket(10, rs) //> res3: Option[(Int, Int)] = None

Alternative if you know the edge cases can't happen:

def bracket(n: Int, rs: List[Int]) = {
  val (l, r) = rs.span(_ < n)
  if (r.head == n)
    (n, n)
  else
    (l.last, r.head)
}                                     
bracket(2, rs)                                  //> res0: (Int, Int) = (1,3)
bracket(6, rs)                                  //> res1: (Int, Int) = (6,6)

(will throw an exception if there is no lower and upper bound for n)

If you can't have edge cases and you are OK with a tuple that is (<=, >) then simply

def bracket(n: Int, rs: List[Int]) = {
  val (l, r) = rs.span(_ <= n)
  (l.last, r.head)
}                                             
bracket(2, rs)                                  //> res0: (Int, Int) = (1,3)
bracket(6, rs)                                  //> res1: (Int, Int) = (6,9)