如何简化if语句写法:为方法传递1或2个参数
如何简化这段Ruby条件判断的find_by代码?
原问题
我想知道有没有更简短、简洁的方式编写以下Ruby代码:
if statement result = model.find_by(key => row[key.to_s]) else result = model.find_by(key => row[key.to_s], secondkey => row[secondkey.to_s]) end
我自己构思了一种思路,但不知道怎么完善:
args = {key => row[key.to_s]} result = model.find_by(args)
补充场景
感谢解答!如果是下面这种场景该怎么写呢?我希望把args = {key => row[key.to_s]}放在循环外面,避免每次循环都执行条件判断:
statement = true rows.each do |row| if statement result = model.find_by(key => row[key.to_s]) else result = model.find_by(key => row[key.to_s], secondkey => row[secondkey.to_s]) end # 更多代码 end
解答
针对单个条件判断的简化
你的思路方向完全正确!可以通过动态合并哈希或者条件展开参数的方式来简化,不用分开写两个find_by调用:
- 动态合并哈希(可读性优先)
args = { key => row[key.to_s] } # 仅当statement为false时,追加第二个键值对 args[secondkey] = row[secondkey.to_s] unless statement result = model.find_by(args)
- 紧凑的条件参数展开(一行式风格)
利用Ruby的关键字参数展开语法(**),直接在find_by调用内处理条件:
result = model.find_by( key => row[key.to_s], **(statement ? {} : { secondkey => row[secondkey.to_s] }) )
如果statement为true,就展开一个空哈希,相当于只传入第一个参数;否则展开包含第二个键值对的哈希,简洁又直观。
针对循环场景的优化(避免重复条件判断)
要把条件判断移到循环外,核心是提前封装好查询参数的生成逻辑,让循环只负责调用逻辑而不做判断,这里推荐两种实用方式:
- 使用Proc预定义逻辑(轻量灵活)
statement = true # 循环前仅做一次条件判断,生成对应的参数生成器 find_args_generator = if statement ->(row) { { key => row[key.to_s] } } else ->(row) { { key => row[key.to_s], secondkey => row[secondkey.to_s] } } end rows.each do |row| result = model.find_by(find_args_generator.call(row)) # 更多代码 end
也可以用三元运算符简化Proc的定义:
find_args_generator = statement ? ->(row) { { key => row[key.to_s] } } : ->(row) { { key => row[key.to_s], secondkey => row[secondkey.to_s] } }
- 封装成方法(可读性更强,适合复杂场景)
如果参数较多或者后续逻辑可能扩展,把参数生成逻辑封装成方法会更清晰:
def build_find_params(row, statement, key, second_key) params = { key => row[key.to_s] } params[second_key] = row[second_key.to_s] unless statement params end statement = true rows.each do |row| result = model.find_by(build_find_params(row, statement, key, secondkey)) # 更多代码 end
这种方式实现了逻辑解耦,后续修改参数生成规则只需要调整方法即可,不用改动循环内的代码。
内容的提问来源于stack exchange,提问作者Databaas7894
相关产品推荐
相关产品推荐

