如何避免具有相似内容的长 if 链
How to avoid long if chain with similar content
我目前正在编写一个 R 函数 get_line_type(line)
来输出一行(字符串)的 type。对于每个当前可能的类型,都有一个 is_TYPENAME_line(line)
形式的函数,其中 returns 一个布尔值,指示该行是否属于此特定类型。将这些 is_TYPENAME_line
函数链接在一起创建 get_line_type(line)
函数,目前看起来像这样
is_fish_line <- function(line) {
return (any(grep("fish", line)))
}
is_mouse_line <- function(line) {
return (any(grep("mouse", line)))
}
get_line_type <- function(line) {
identified_types <- character(0)
if(is_fish_line(line)) { identified_types[length(identified_types) + 1] <- "FISH" }
if(is_mouse_line(line)) { identified_types[length(identified_types) + 1] <- "MOUSE" }
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")
}
这段代码是这样工作的
> get_line_type("The fish seems happy.")
[1] "FISH"
> get_line_type("A mouse is living in this house.")
[1] "MOUSE"
> get_line_type("The tiger is the king of the jungle.")
[1] "UNKOWN"
> get_line_type("The fish and the mouse are friends.")
Error in get_line_type("The fish and the mouse are friends.") :
Matched multiple types: FISH, MOUSE Line: The fish and the mouse are friends.
在函数内部创建了一个列表 identified_types
,其中包含参数行的所有已识别类型的名称。如果未找到类型,则返回 UNKOWN
。如果恰好识别出一种类型,则返回识别出的类型。如果识别出不止一种类型,则会发生错误(这不应该发生)。
将来可能的类型列表可能会增加,我可以在链中添加另一个 if
语句来完成这项工作,但我想知道是否有更优雅的方法,因为每个条件看起来都很相似。
我不确定这是否是您要找的,但这里有一些事情需要考虑:
创建一个向量,其中包含您在函数中包含的 "TYPENAMES"。然后,您可以动态构建这些函数并将其放入名为 funcList
.
的命名列表中
您的 get_line_type
函数可以调用所有函数并提供 line
作为参数。结果可以很容易地简化,因为你从这些函数中 return TRUE
或 FALSE
。
我注意到您在评论中可能有两个词带有 space(例如,"product search")。在 all_types
中,您需要在这些词之间加上下划线以创建没有 space 的可用函数。此外,如果需要,可以修改 identified_types
以删除下划线。
all_types <- c("fish", "mouse")
funcList <- lapply(all_types, function(x) eval(parse(text = paste0('is_', x, '_line'))))
names(funcList) <- all_types
get_line_type <- function(line) {
lst <- lapply(funcList, do.call, list(line))
identified_types <- names(lst[unlist(lst)])
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 "UNKNOWN")
}
我目前正在编写一个 R 函数 get_line_type(line)
来输出一行(字符串)的 type。对于每个当前可能的类型,都有一个 is_TYPENAME_line(line)
形式的函数,其中 returns 一个布尔值,指示该行是否属于此特定类型。将这些 is_TYPENAME_line
函数链接在一起创建 get_line_type(line)
函数,目前看起来像这样
is_fish_line <- function(line) {
return (any(grep("fish", line)))
}
is_mouse_line <- function(line) {
return (any(grep("mouse", line)))
}
get_line_type <- function(line) {
identified_types <- character(0)
if(is_fish_line(line)) { identified_types[length(identified_types) + 1] <- "FISH" }
if(is_mouse_line(line)) { identified_types[length(identified_types) + 1] <- "MOUSE" }
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")
}
这段代码是这样工作的
> get_line_type("The fish seems happy.") [1] "FISH" > get_line_type("A mouse is living in this house.") [1] "MOUSE" > get_line_type("The tiger is the king of the jungle.") [1] "UNKOWN" > get_line_type("The fish and the mouse are friends.") Error in get_line_type("The fish and the mouse are friends.") : Matched multiple types: FISH, MOUSE Line: The fish and the mouse are friends.
在函数内部创建了一个列表 identified_types
,其中包含参数行的所有已识别类型的名称。如果未找到类型,则返回 UNKOWN
。如果恰好识别出一种类型,则返回识别出的类型。如果识别出不止一种类型,则会发生错误(这不应该发生)。
将来可能的类型列表可能会增加,我可以在链中添加另一个 if
语句来完成这项工作,但我想知道是否有更优雅的方法,因为每个条件看起来都很相似。
我不确定这是否是您要找的,但这里有一些事情需要考虑:
创建一个向量,其中包含您在函数中包含的 "TYPENAMES"。然后,您可以动态构建这些函数并将其放入名为 funcList
.
您的 get_line_type
函数可以调用所有函数并提供 line
作为参数。结果可以很容易地简化,因为你从这些函数中 return TRUE
或 FALSE
。
我注意到您在评论中可能有两个词带有 space(例如,"product search")。在 all_types
中,您需要在这些词之间加上下划线以创建没有 space 的可用函数。此外,如果需要,可以修改 identified_types
以删除下划线。
all_types <- c("fish", "mouse")
funcList <- lapply(all_types, function(x) eval(parse(text = paste0('is_', x, '_line'))))
names(funcList) <- all_types
get_line_type <- function(line) {
lst <- lapply(funcList, do.call, list(line))
identified_types <- names(lst[unlist(lst)])
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 "UNKNOWN")
}