Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter with * which will restrain all values that starts with Null?

I have the following code which extends my filter functionality to allow me to search for more than one Zip-code. Ex. (1254,125,145,1455)

Current Code:

if (Post_Code_PAR != null)
{
    String[] PostCode_Array = Post_Code_PAR.Split(',');
    query = from p in query where PostCode_Array.Contains(p.Post_Code) select p;
}

I want to extend this code in a way that if I give it something like (0*) it will find zip codes which starts with 0. If I give it 123* it will give me all zip codes which starts with 123. Thanks a lot.

like image 409
Dragon Avatar asked Feb 10 '23 10:02

Dragon


2 Answers

use regular expression:

  • https://msdn.microsoft.com/en-us/library/ms228595.aspx
  • https://msdn.microsoft.com/en-us/library/az24scfc(v=vs.110).aspx

example:

IEnumerable<string> allInputs = new[] {"70000", "89000", "89001", "90001"};
string commaSeparatedPostCodePatterns = @"89000 , 90\d\d\d";

if (string.IsNullOrWhiteSpace(commaSeparatedPostCodePatterns)) 
    return;

string[] postCodePatterns = commaSeparatedPostCodePatterns
                                .Split(',')
                                .Select(p => p.Trim()) // remove white spaces
                                .ToArray();

var allMatches = 
    allInputs.Where(input => postCodePatterns.Any(pattern => Regex.IsMatch(input, pattern)));

foreach (var match in allMatches)
    Console.WriteLine(match);

With such a problem, the initial requirements are very simple but quickly become more and more complex (due to internationalization, exceptions to the rule, some smart tester testing an unexpected limit-case like 90§$% ...). So regular expressions provide the best trade-off simplicity vs. extendability

The regex equivalent to * is .*. But in your case, you would rather need more restrictive patterns and use the \d placeholder matching a single digit. Optional digit would be \d?. Zero or more digits would be \d*. One or more digits would be \d+. Please look at the documentation for more details.

like image 164
jeromerg Avatar answered Feb 13 '23 03:02

jeromerg


You can replace the * with \d* which is the Regex way of saying "any amount of digits", basically. Then run through and filter with Regex.IsMatch().

if (Post_Code_PAR != null)
{
    var PostCode_Array = from p in Post_Code_PAR.Split(',') select String.Format("^{0}$", p.Replace("*", @"\d*"));
    query = (from p in query where PostCode_Array.Any(pattern => Regex.IsMatch(p.Post_Code, pattern)) select p).ToArray();
}

I tried to keep it as close to your code as possible but you could clean it up a bit and use lambda instead. But this should work just as well :)

like image 42
Hjalmar Z Avatar answered Feb 13 '23 04:02

Hjalmar Z