4

Just found out that this comparison is actually case-sensitive..Anyone know a case-insensitive way of accomplishing the same comparison?

CardReferral.all.map(&:email) - CardSignup.all.map(&:email)
Jo Liss
  • 30,333
  • 19
  • 121
  • 170
Trip
  • 26,756
  • 46
  • 158
  • 277

1 Answers1

9

I don't think there is any "direct" way like the minus operator, but if you don't mind getting all your results in lowercase, you can do this:

CardReferral.all.map(&:email).map(&:downcase) - CardSignup.all.map(&:email).map(&:downcase)

Otherwise you'll have to manually do the comparison using find_all or reject:

signups = CardSignup.all.map(&:email).map(&:downcase)
referrals = CardReferral.all.map(&:email).reject { |e| signups.include?(e.downcase) }

I'd suggest that reading a reference of Ruby's standard types might help you come up with code like this. For example, "Programming Ruby 1.9" has all methods of the Enumerable object explained starting on page 487 (find_all is on page 489).

Jo Liss
  • 30,333
  • 19
  • 121
  • 170
  • on a side note : What exactly is this "(&:" mean? – Trip Dec 02 '10 at 20:30
  • both of these include needless iterations. `map { |c| c.email.downcase }` or `reject { |c| signups.index(c.email.downcase) }` will work just fine – thorncp Dec 02 '10 at 20:34
  • @Trip: Google for 'ruby ampersand operator'. It's the Symbol#to_proc method. http://stackoverflow.com/questions/1961030/ruby-ruby-on-rails-ampersand-colon-shortcut – Jo Liss Dec 02 '10 at 20:43
  • 1
    @thorncp: I think either way is fine. Most of the performance-sensitive stuff happens in the database anyway, and in terms of readability they're both equally concise. `reject { |c| signups.index(c.email.downcase) }` by the way doesn't quite do the same thing since it gives you CardReferral objects, not strings. – Jo Liss Dec 02 '10 at 20:45
  • 1
    `signups.include?` would indicate intent better than `signups.index`. – Andrew Grimm Dec 02 '10 at 22:33