You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于多条件优雅简洁地向数组中添加多个元素?

当然有更优雅的写法!

咱们先看看你的原代码:

def call
  banners = []
  banners.push(banner1) if condition1?
  banners.push(banner2) if condition2?
  banners.push(banner3) if condition3?
  banners
end
def banner1
  { type: BANNER1, display_value: 'banner_1' }
end
# 假设还有banner2、banner3方法

这段代码的核心逻辑是根据对应条件收集符合要求的banner,但重复的push和if判断显得有点冗余。下面给你几种更简洁优雅的写法:

方案1:用条件-banner配对数组 + 筛选提取

把每个条件和对应的banner打包成数组,通过筛选和映射一步得到结果:

def call
  [
    [condition1?, banner1],
    [condition2?, banner2],
    [condition3?, banner3]
  ].select { |condition, _| condition }.map(&:last)
end

def banner1
  { type: BANNER1, display_value: 'banner_1' }
end
# banner2、banner3方法保留

这样就去掉了重复的push和if,逻辑更集中,一眼就能看到所有条件和对应banner的关联。

方案2:内联banner定义(适合简单逻辑)

如果你的banner逻辑像例子里这么简单,完全可以把banner的哈希直接写进配对数组里,省去单独的方法:

def call
  [
    [condition1?, { type: BANNER1, display_value: 'banner_1' }],
    [condition2?, { type: BANNER2, display_value: 'banner_2' }],
    [condition3?, { type: BANNER3, display_value: 'banner_3' }]
  ].select { |cond, _| cond }.map(&:last)
end

行数直接减少了一半,代码更紧凑。

方案3:用Ruby 2.7+的filter_map一步到位

Ruby 2.7以后新增了filter_map方法,可以把筛选和映射合并成一步,代码更短:

def call
  [
    [condition1?, banner1],
    [condition2?, banner2],
    [condition3?, banner3]
  ].filter_map { |cond, banner| banner if cond }
end

filter_map会自动忽略块返回nil的元素,完美适配咱们的场景,一行搞定筛选和收集。

这些写法都保留了原逻辑的清晰度,同时大幅减少了重复代码,你可以根据banner的实际复杂度选择合适的方案~

内容的提问来源于stack exchange,提问作者prajeesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 10:52:27