## Ruby make list minimum length

In a Ruby on Rails app, I wanted a list to be at least of two items. This could be done in several ways.

Here is a first naïve impementation:

``````
# Naïve implementation, just return whatever number I need
def sum_up_a(existing)
return 2 if existing == 0
return 1 if existing == 1
return 0
end

sum_up_a(0)   # => 2
sum_up_a(1)   # => 1
sum_up_a(2)   # => 0
sum_up_a(3)   # => 0
sum_up_a(10)  # => 0

``````

A slightly improved version could investigate number of existing, and return the diff only if needed:

``````
MIN_COUNT = 2
# slightly improved with less conditionals
def sum_up_b(existing)
return 0 if existing >= MIN_COUNT
MIN_COUNT - existing
end

sum_up_b(0)   # => 2
sum_up_b(1)   # => 1
sum_up_b(2)   # => 0
sum_up_b(3)   # => 0
sum_up_b(10)  # => 0
``````

Now, my favourite. If you look at the result of “MIN_COUNT – existing”. This number is negative or zero if we dont want extra rows. This means that we can rewrite the algorithm without any conditional logic like this:

``````
# my favorite: return the biggest number either 0 or the difference
# Works well because difference is only positive for numbers where I
# need some extra rows
def sum_up_c(existing)
[MIN_COUNT - existing, 0].max
end

sum_up_c(0)   # => 2
sum_up_c(1)   # => 1
sum_up_c(2)   # => 0
sum_up_c(3)   # => 0
sum_up_c(10)  # => 0
``````

I like the latter, since too many conditional statements tend to clutter the logic. Just a short tip and a reminder for myself next time I run into this kind of problem.

Complete example gist avalilable on Github:

### 2 Responses to “Ruby make list minimum length”

1. Jakob S Says:

I’d argue the first, naive implementation is the optimal one. Sure, option C might be clever, but I couldn’t tell you what it does without running the code in my head. Clever is rarely a quality to aim for: https://medium.com/@mikesherov/writing-clear-code-not-clever-code-d6b90353a3c5#.rkedlie16 ;)

If you don’t like the return statements you could go for a case statement instead:

def sum_up_case(existing)
case existing
when 0
2
when 1
1
else
0
end
end

or potentially a lookup table if the above is too verbose:

def sum_up_lookup(existing)
{
0 => 2,
1 => 1
}.fetch(existing, 0)
end

2. Jesper Says:

I gonna pass this link to my colleague, who strugles with sort of same problem