Home > Mobile >  Clean way to push multiple items to array based on multiple conditions
Clean way to push multiple items to array based on multiple conditions

Time:09-16

The code is as follows.

    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

Is there a more cleaner way to write this? May be with fewer lines of code?

CodePudding user response:

One way to not be a human compiler is to use loops:

def call
  [:banner1, :banner2, :banner3].filter_map do |name|
    send(name) if send("#{name}?")
  end
end

This assumes that there is some sort of correlation between the name of the method you want to call and the prejudicate method.

If not use a hash instead:

def call
  {
    banner1: :condition1?,
    banner2: :condition2?,
    banner3: :condition3?
  }.filter_map do |method, condition|
    send(method) if send(condition)
  }
end

Of course this really begs the question if these methods could just by DRY:ed into a single method that takes arguments or if other refactoring is needed.

CodePudding user response:

If it's possible for you to move conditions into banner methods:

def call
  [banner1, banner2, banner3].reject(&:empty?)
end

def banner1
  return {} unless condition1?
  {
    type: BANNER1,
    display_value: 'banner_1'
  }
end

def banner2
  return {} unless condition2?
  {
    type: BANNER2,
    display_value: 'banner_2'
  }
end

def banner3
  return {} unless condition3?
  {
    type: BANNER3,
    display_value: 'banner_3'
  }
end
  • Related