0

I would like to extract an element from an array, predictably based on a string input.

My use case: Generate a color for a user, based on name.

One (faulty) implementation would be to generate a hash from the user name, and reduce it to a value between 0-25 like so:

def color
  colors = array_of_25_colors
  colors[Digest::MD5.hexdigest(name).to_i(16) & 25]
end

This implementation only returns 8 possible colors, so no good.

EDIT

Another implementation I've tried is to use the byte code from the first character in the name, but since I allow unicode in names this is not practical:

"aaron".first.bytes.first - 97
=> 0 #Okay!
"zac".first.bytes.first - 97
=> 25 #Nice!
"örjan".first.bytes.first - 97
=> 98 #Doh!

What could a working implementation look like?

Richard Johansson
  • 430
  • 1
  • 5
  • 12

2 Answers2

2

You can add up the ordinal values of each character in the string then divide mod 25 like this:

colors = array_of_25_colors
colors[name.bytes.reduce(:+) % 25]
bundacia
  • 1,036
  • 5
  • 13
2

Building on your use of #bytes, you could also go with something like:

colors[name.bytes.inject(:+) % 25]
theTRON
  • 9,608
  • 2
  • 32
  • 46