R语言如何简洁实现多对象类属性的批量校验判断
R列表类型校验函数优化实现
需求说明
为保障自定义函数运行性能,需要对传入对象完成类型校验,判定规则如下:
- 第一类合法对象:同时满足三层类型要求——外层为
list、第一个子元素为character、第二个子元素为character,判定通过 - 第二类合法对象:同时满足三层类型要求——外层为
list、第一个子元素为character、第二个子元素为numeric,判定通过
初始硬编码实现如下,待校验列表元素较少时可正常运行,但当列表元素规模扩大到15个及以上时,逐元素重复写判断逻辑会导致代码冗余杂乱、可维护性极差:
first_class <- list('prediction','median') second_class <- list('prediction', c(1, 2, 3, 4)) test_class_object <- function(class_object) { if (is(class_object, 'list') == TRUE & is(class_object[[1]], 'character') == TRUE & is(class_object[[2]], 'character') == TRUE) { print('all characters') } else if (is(class_object, 'list') == TRUE & is(class_object[[1]], 'character') == TRUE & is(class_object[[2]], 'numeric') == TRUE) { print('last is numeric') } }
优化后可复用版本
核心优化思路是抽离公共的类型提取、外层校验逻辑,将重复判断合并,同时预留扩展空间适配后续业务场景:
library(magrittr) # 支持%>%管道操作,若已加载tidyverse可忽略 test_class_object <- function(class_object) { # 统一做外层类型校验,提前拦截非法输入 if(!is(class_object,'list')){ stop("You need a list object, for example: list('prediction','median')") } # 批量提取所有子元素的主类型,避免逐元素重复写is判断 elem_types <- c(class(class_object), sapply(class_object, function(x)class(x)[1])) # 按规则匹配类型 if (last(elem_types) == 'character') { print('all characters') } else if (last(elem_types) == 'numeric') { print('last is numeric') } else { print('not found') } }
优化点说明
- 外层
list校验只做一次,非法输入直接抛出错误,减少无效计算 - 子元素类型通过
sapply批量提取,不管列表后续扩展到多少个元素,都不需要逐行追加is()判断 - 类型匹配逻辑和类型提取逻辑解耦,后续新增校验规则时只需要追加匹配分支即可,不需要改动底层校验逻辑
后续扩展建议
当前版本默认取每个子元素的第一个类做判断,适配现阶段列表内均为单类对象的场景。后续如果业务中出现包含多类属性的对象,只需要调整子元素类型提取的逻辑,例如将class(x)[1]替换为"目标类" %in% class(x)的判断逻辑即可,不需要重构整体函数框架。
内容的提问来源于stack exchange,提问作者tesla john
相关产品推荐
相关产品推荐

