Search code examples
c#windows-phone-8combinations

Find letter combination on phone keypad


I'm working on an app which is a dialer and I want to search contacts when user presses keys. I want to search contacts which match phone number as well as name of contact. I've implemented method to search contact based on phone number, when user presses key, it'll search the number similar to the keys pressed.

My code is:

List<string> a = new List<string>();
var alphabet = "abc";
var al2 = "def";

var q = alphabet.Select(x => x.ToString());
int size = 3;
for (int i = 0; i < size - 1; i++)
    q = q.SelectMany(x => al2, (x, y) => x + y);

foreach (var item in q)
    a.Add(item);

SearchListbox.ItemsSource = listobj
    .FindAll(x => x.Phone.Contains(str) || 
        x.FirstName.Contains(a.Any().ToString()));

It works perfectly for number search but not for name search.

I want to search contacts which match letter combinations when user presses keys. How do I do that? I'm building an app for windows phone so it must be in c#.


Solution

  • this is a good job for regular expressions! here's an example i whipped up to use regex to search through:

            var names = new List<string>();
            names.Add("alice");
            names.Add("bob");
            names.Add("charlie");
    
            var digitMap = new Dictionary<int, string>()
            {
                { 1, "" },
                { 2, "[abcABC]" },
                { 3, "[defDEF]" },
                { 4, "[ghiGHI]" },
                { 5, "[jklJKL]" },
                { 6, "[mnoMNO]" },
                { 7, "[pqrsPQRS]" },
                { 8, "[tuvTUV]" },
                { 9, "[qxyzQXYZ]" },
                { 0, "" },
            };
    
            var enteredDigits = "26";
            var charsAsInts = enteredDigits.ToCharArray().Select(x => int.Parse(x.ToString()));
    
            var regexBuilder = new StringBuilder();
            foreach (var val in charsAsInts)
                regexBuilder.Append(digitMap[val]);
    
            var pattern = regexBuilder.ToString();
    
            //append a ".*" to the end of the regex to make it "StartsWith", beginning for "EndsWith", or both for "Contains";
            pattern = ".*" + pattern + ".*";
    
            var matchingNames = names.Where(x => Regex.IsMatch(x, pattern));
    
            Console.WriteLine("Matching input: " + enteredDigits + " as regex: " + pattern);
    
            foreach (var n in matchingNames)
                Console.WriteLine(n);
    

    In this example, I had "26" as the input, which filters out all but "bob". If you remove the 6 you'll find it returns all three, as they all have a, b, or c in their names.

    FYI, if you wanted it to match the number as well, simply add the number to the regex string value in the dictionary.