Skip to content

Instantly share code, notes, and snippets.

@madrobby
Created December 21, 2014 18:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save madrobby/27b537ab0344c827daf8 to your computer and use it in GitHub Desktop.
Save madrobby/27b537ab0344c827daf8 to your computer and use it in GitHub Desktop.
letters = ""
letters << user.first_name[0,1] if user.first_name.size > 1 && 'A'..'Z'.include?(user.first_name[0,1].upcase)
letters << user.last_name[0,1] if user.last_name.size > 1 && 'A'..'Z'.include?(user.last_name[0,1].upcase)
@madrobby
Copy link
Author

Ruby gives me a warning: string literal in condition for this.

What's a better way to write this? I want a string that contains the first characters of user.first_name and user.last_name, but only if they are letters from A to Z.

Note: If either of the characters is not a letter from A to Z it's fine if letters stays empty.

@madrobby
Copy link
Author

Perhaps something like:

[user.first_name,user.last_name].map{|part| (part||'').scan(/^[A-Z]/i)}.flatten.join

@prakashmurthy
Copy link

Changing 'A'..'Z'.incude? to ('A'..'Z').to_a.include fixes warning: string literal in condition .

@triskweline
Copy link

letters = /([A-Z]+)/.match(user.first_name[0] + user.last_name[0]).to_s

Although this or your previous iteration is more clever, your original code is a lot clearer.

@mikebowler
Copy link

How about
letters = ('' << user.first_name[0].to_s << user.last_name[0].to_s).gsub(/[^A-Z]+/, '')

@jarkko
Copy link

jarkko commented Dec 21, 2014

letters = ""
[user.first_name, user.last_name].each do |field|
  letters += field[0] if field.present? && field =~ /\A[a-z]/i
end

Assumes Rails and is not the clever solution, but rather following the clarity level of the original. Could use inject as well of course.

@triskweline
Copy link

I like @jarkko's solution for its non-cleverness.

@jarkko
Copy link

jarkko commented Dec 21, 2014

Or the official MapReduceTM version:

letters = [user.first_name, user.last_name].select {|field|
  field.present? && field =~ /\A[a-z]/i
}.map {|chosen|
  chosen[0]
}.join

@madrobby
Copy link
Author

@prakashmurthy thanks!
@henning-koch, @jarkko: The original is pretty easy to read, yeah. I might just go with the extra parens.
@mikebowler: interesting approach that avoids the loop, thanks!

@madrobby
Copy link
Author

Took a stab and combined @jarkko's approach with the original that doesn't use regular expressions:

letters = [user.first_name, user.last_name].map do |part|
  part[0,1] if part.present? && ('A'..'Z').include?(part[0,1].upcase)
end.join

@til
Copy link

til commented Dec 21, 2014

Nice ruby puzzle ;-). What about String#[] with a regex capture group? The dot in the regex enforces the length to be >= 2.

letters = [user.first_name, user.last_name].map { |name| name[/^([a-z])./i, 1] }.compact

@lrz
Copy link

lrz commented Dec 21, 2014

I would write it like this:

letters = [first_name, last_name].map { |x| x[0] if ('A'..'Z').include?(x[0]) }.join

@madrobby
Copy link
Author

@lrz Yeah, basically what I ended up with. Note that I have an extra test because first/last name could be nil.

@stefanoc
Copy link

letters = "#{first_name[0]}#{last_name[0]}".gsub(/[^A-Z]/, '')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment