samedi 21 mars 2020

How to avoid long if chain with similar content

I'm currently writing an R function get_line_type(line) to output the type of a line (a string). For every currently possible type there is a function of the form is_type_TYPENAME(line) which returns a boolean value indicating whether the line is of this specific type. Chaining these is_type_TYPENAME together creates the get_line_type(line) function and currently looks like this

get_line_type <- function(line) {
  identified_types <- character(0)

  if(is_age_question_line(line)) { identified_types[length(identified_types) + 1] <- "AGE_QUESTION" }
  if(is_fuel_amount_line(line)) { identified_types[length(identified_types) + 1] <- "FUEL_AMOUNT" }
  if(is_fuel_price_line(line)) { identified_types[length(identified_types) + 1] <- "FUEL_PRICE" }
  if(is_part_of_row_storno_line(line)) { identified_types[length(identified_types) + 1] <- "ROW_STORNO" }
  if(is_product_amount_line(line)) { identified_types[length(identified_types) + 1] <- "FUEL_PRICE" }
  if(is_product_id_line(line)) { identified_types[length(identified_types) + 1] <- "PRODUCT_ID" }
  if(is_product_label_line(line)) { identified_types[length(identified_types) + 1] <- "PRODUCT_LABEL" }
  if(is_product_list_total_seperator_line(line)) { identified_types[length(identified_types) + 1] <- "PRODUCT_LIST_TOTAL_SEPERATOR" }
  if(is_product_search_line(line)) { identified_types[length(identified_types) + 1] <- "PRODUCT_SEARCH"}
  if(is_tax_message_line(line)) { identified_types[length(identified_types) + 1] <- "TAX_MESSAGE" }

  if (length(identified_types) > 1) {
    stop("Matched multiple types: ", paste(identified_types, collapse = ", "), "\t", "Line: ", line)
  }

  return(if(length(identified_types) == 1) identified_types[1] else "UNKOWN")
}

Inside the function a list identified_types with the names of all the identified types for the argument line. If no type was found UNKOWN is returned. If exactly one type was identified the identified type is returned. If more than one type was identified an error occurs (this should not happen).

In the future the list of possible types may grow and I can just add another if-statement into the chain to make this work, but I was wondering if there was a more elegant approach to this, since each conditional looks so similar.

Aucun commentaire:

Enregistrer un commentaire