能否简化这款按LOG_NAME筛选输出日志的Ruby方法?
优化后最简实现(完全移除if/else分支)
LOGS = [{ "first_log" => ["first task"] }, { "second_log" => ["second task"] }, { "third_log" => ["third task", "additional task"] }] LOG_NAME = "second_log" def output LOGS.filter { !LOG_NAME || _1.key?(LOG_NAME) }.each do |log| name, tasks = log.first puts "-#{name}:", " Tasks: #{tasks.join(',')}" end end
优化思路
核心逻辑是把分支判断合并到过滤规则中,不需要单独拆分分支处理,过滤条件会自动适配两种场景:
- 当LOG_NAME为假值时,
!LOG_NAME条件成立,所有日志条目都会被保留 - 当LOG_NAME为真值时,仅保留键名匹配LOG_NAME的条目
同时做了两处隐性优化:
- 用
log.first直接解构获取日志名称和任务数组,替代原代码分别取keys、values的冗余写法,更简洁 - 修复了原代码直接对
log.values做join的隐藏问题:原结构中每个日志哈希只有一个键值对,log.values返回的是嵌套数组,直接join会出现多余的转义字符,取first拿到实际任务数组后再join才符合预期
可选调整
如果你需要严格判断「LOG_NAME常量是否被定义」(而不是判断值是否为真),只需要修改过滤条件即可:
LOGS.filter { !defined?(LOG_NAME) || _1.key?(LOG_NAME) }.each do |log| # 输出逻辑不变 end
如果确认日志名称全局唯一,还可以把filter换成find进一步提升性能,避免遍历整个数组:
def output target = defined?(LOG_NAME) ? LOGS.find { _1.key?(LOG_NAME) } : nil (target ? [target] : LOGS).each do |log| name, tasks = log.first puts "-#{name}:", " Tasks: #{tasks.join(',')}" end end
内容的提问来源于stack exchange,提问作者user15788830
相关产品推荐
相关产品推荐

