1

My project was working just fine until I had to account for an array of strings and not just one... I don't know how to fix this. The Country is a property of the current class this method is in. It used to be a single string but now is an array.

Originally it looked like this:

private Expression<Func<Payment, bool>> CountryMatches()
{
   if (Country.Length < 1) return Skip;
   return payment => payment.Country.ToLower().Contains(Country.ToLower());
}

What I can't figure out is how to set it up so that if ANY of the strings in Country match payment.Country... and of course this is passing back an expression... This is my best guess (but obviously not correct) of how to do what I need to do:

private Expression<Func<Payment, bool>> CountryMatches()
{
   if (Country.Length < 1) return Skip;
   return payment => payment.Country.ToLower() == Country.Any().ToLower();
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
MegaMark
  • 600
  • 8
  • 26
  • possible duplicate of [C# Determing whether any element in a string array contains a given string anywhere](http://stackoverflow.com/questions/3895809/c-sharp-determing-whether-any-element-in-a-string-array-contains-a-given-string) – JK. May 15 '14 at 21:31

2 Answers2

6

You want to check all the contents of Country against payment.Country, like this:

return payment => Country.Any(
    c => payment.Country.ToLower().Contains(c.ToLower()));

That said, this is a rather bad way to check if one string is a substring of another mainly because it does a lot of unnecessary work by converting to lowercase again and again. Here's a better way to do it:

return payment => Country.Any(
    c => payment.Country.IndexOf(c, StringComparison.OrdinalIgnoreCase) >= 0);
Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806
  • You should change your answer to point that the first option incurs in unnecessary creation of strings due to the calls to `ToLower`. The second option is better in the way that it's good and the first is bad. – Paulo Morgado May 16 '14 at 01:09
  • @PauloMorgado: I didn't want to put too much focus into that because it's not directly related to the question, but you are right in that it should be called out. Edited. – Jon May 16 '14 at 12:51
2

.Any Takes a lambda in, which can perform your comparison. The above code assums it returns some object which equates to true when compared, but Any returns a simple bool. Thus, try

return payment =>
    Country.Any(c =>
        string..Equals(payment.Country, c, StringComparison.InvariantCultureIgnoreCase));

Also note that .Equals is often preferable to the "==" operator, particularly with strings, wherin you can pass the StringComparison parameter.

David
  • 10,458
  • 1
  • 28
  • 40