Home > OS >  What's the best way to check if a non-numeric value is in a range?
What's the best way to check if a non-numeric value is in a range?

Time:02-11

Sometimes, thinking about the best algorithm is tricky. Well I have to work with some ranges of the form "letter/number/number", for example X86-Z95 would be a range. Actually I need to see if a given code is in the code range. I thought I'd generate an array containing the ranges and check if the code is in the array. But as I had a lot of work to implement the algorithm, I think there is an easier way to implement it. I would like to see some more efficient or elegant solution. I leave my code below.

Thanks in advance!

library(stringr)
generateInterval = function(str_interval) {
  limits = strsplit(str_interval, '-')[[1]]
  letters_limits = substr(limits, 1, 1)
  numbers_limits = as.numeric(substr(limits, 2, 3))
  if (letters_limits[1] == letters_limits[2]) {
    interval = paste0(letters_limits[1], numbers_limits[1]:numbers_limits[2])
  } else {
    pos = which(LETTERS %in% letters_limits)
    interval_letters = LETTERS[pos[1]:pos[2]]
    numbers = as.numeric(substr(limits, 2, 3))
    interval = c()
    for (i in 1:length(interval_letters)) {
      if (i == 1) {
        interval = c(interval, paste0(interval_letters[i], numbers[1]:99))
      } else if (i == length(interval_letters)) {
        interval = c(interval, paste0(interval_letters[i], 0:numbers[2]))
      } else {
        interval = c(interval, paste0(interval_letters[i], 0:99))
      }
    } 
  }
  interval = ifelse(str_length(interval) == 2,
                    paste0(substr(interval, 1, 1), 0, substr(interval, 2, 2)),
                    interval)
  
  return(interval)
}

generateInterval('A72-B10')

CodePudding user response:

Following the OP's comment here is a way in base R. The only thing that needs to be done is to realize that R can compare strings. And the one-line function will check if the codes are within range.

within_range <- function(x, lower, upper) lower <= x & x <= upper

within_range(c("X92", "X84", "A10", "Y30"), lower = "X86", upper = "Z95")
#> [1]  TRUE FALSE FALSE  TRUE

Created on 2022-02-11 by the reprex package (v2.0.1)

  • Related