Skip to main content
Published in Engineering Insights

Code Golf: Conditionally Add To An Array

Code Golf: Conditionally Add To An Array
Table of contents
  1. The Grass Is Always Greener
  2. Teeing Up An Option
  3. Tapping It In
  4. Taking a Compact Swing
  5. Working On Your Backswing Takeaway
  6. Selecting The Right Club
  7. Asking Help From The Caddie

The Grass Is Always Greener#

We're building a system to track a golfer's statuses during a tournament. This isa competitive tournament with people who are much better than I will ever be, soif a golfer is currently scoring under par, they're in contention to win. On this 18 hole course, if they've played the first nine holes, they've made the turn.Let's explore a number of ways we can build up an array that keeps track ofwhich, if any, of these statuses a particular golfer qualifies for. Not content to settle for one that works, we'll dig into a variety of options.

Teeing Up An Option#

We can start with an empty array, and explicitly add in any of the statuses thatthe golfer meets the conditions for.

Ruby
def current_statuses
  statuses = []

  if under_par?
    statuses << "in_contention"
  end

  if back_nine?
    statuses << "past_the_turn"
  end

  statuses
end

‍There's nothing tremendously exciting here, and that's not a bad thing! It'sreasonably clear what this is doing.

Tapping It In#

We can make the prior suggestion a little more terse by using tap.

Ruby
def current_statuses
  [].tap do |statuses|
    if under_par?
      statuses << "in_contention"
    end

    if back_nine?
      statuses << "past_the_turn"
    end
  end
end

This eliminates the need for the statuses temporary array from the priorsection.

Taking a Compact Swing#

We can also build our array to have an entry for each of the conditionals wehave, and removing the ones that aren't relevant.

Ruby
def current_statuses
  [
    under_par? ? "in_contention" : nil,
    back_nine? ? "past_the_turn" : nil,
  ].compact
end

By using compact,we'll remove any nil values, and we'll take advantage of that functionalityby explicitly adding nil if the golfer doesn't meet that condition.

Working On Your Backswing Takeaway#

Speaking of taking things away, we can also do the opposite of the first approach. We'll start by having each status, and then removing the ones thatdo not meet the necessary condition.

Ruby
def current_statuses
  statuses = ["in_contention", "past_the_turn"]

  unless under_par?
    statuses -= ["in_contention"]
  end

  unless back_nine?
    statuses -= ["past_the_turn"]
  end

  statuses
end

This may be more helpful in situations where there are a lot more statuses, andonly a few of them may need to be removed for certain reasons. It may also helpwhen the full list of statuses persists on its own elsewhere, but then you alsoneed a subset of them in a particular case.

Selecting The Right Club#

Lastly, we'll put together a hash keyed on the statuses where the value is the result of the conditions. We can then flex some familiarity with Ruby's Enumerable module to pick out the applicable sections of the hash, returning only the statuses.

Ruby
def current_statuses
  {
    "in_contention" => under_par?,
    "past_the_turn" => back_nine?,
  }.select { |_status, condition| condition }.keys
end

Similar to the prior suggestion, this may be helpful when you want to have thefull list of statuses and their associated conditions all compiled in one place,but then want to peel off which are relevant for a particular golfer at thistime.

Asking Help From The Caddie#

Here are some of the ways that we might solve this problem. What other wayscould we build this functionality? Let me knowwhat other approaches you would take.

Learn more about how The Gnar builds Ruby on Rails applications.

Frequently asked questions

How does the simplest version build the array?

It starts with an empty statuses array. It adds "in_contention" when under_par? is true and "past_the_turn" when back_nine? is true, then returns the array.

What does compact do in this example?

Each condition produces either a status string or nil. Calling compact removes the nil values, leaving only the statuses that apply.

When might starting with all statuses help?

It may help when there are many statuses and only a few need removing. It can also help when a full list already exists elsewhere and a particular case needs only a subset.

How does the hash approach work?

The hash uses status strings as keys and condition results as values. select keeps the entries with true conditions, and keys returns their status strings.

Stay In The Loop

Never miss an update. Get the latest blogs, webinars, and expert insights straight to your inbox from The Gnar.