Ruby deck flips

posted by
pete

I'm constantly reminded of why I love Ruby so damn much. I'm not a CompSci scholar, and I know that Lisp did everything first 30 years ago... I guess it's all about context, isn't it?

Luckily, this isn't Reddit and so I'm hoping I can share one of my favourite operators with you. That's right, I have favourite operators. They make me feel like I have crazy ninja Skate or Die skills, even though there's very little mystery.

In Ruby we kick around && and   like nerd footbags, but there are a few operators that you might not have realized, and & is one of them.

& (aka the Intersect)

You can be forgiven if, like me, you initially assume that & is a bitwise AND operator. After all, when applied to a Numeric, that’s exactly what it is. (In brief, 1 & x returns 1 when x is an odd number and 0 if x is even. Good for alternating row colours!)

When applied to two Array objects, it returns the elements that are unique in both:

[1, 2, 3] & [2, 3, 4] # => [2, 3]


How many times have you written inefficient double-loop constructs to compare lists? There’s something deeply satisfying about replacing functions with a single character.

What can you do with this little gem? One of my favourites is a simple function to derive the Tanimoto coefficient. This gives you a Float between 0 and 1 which tells you how similar the contents of two lists are. This is useful for correlating tastes, recommending products, and other predictive applications.

def tanimoto(a, b)
  c = a & b
  c.size.to_f / (a.size + b.size - c.size)
end

x = %w[apple orange banana kiwi]
y = %w[apple pear orange]

puts tanimoto(x, y) # => 0.4