Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to do a partial string match on a Dictionary string key?

I have a Dictionary<string, List<int>> in my code which I am using in the following manner:

Key           Values  
2011-07-15    1, 2, 3
2011-07-20    4, 5, 6
2010-02-11    7, 8, 9

My code needs to be able to query for all values matching a particular substring in the key. For example, if I had the substring 2011-07 it should return values {1, 2, 3, 4, 5, 6}. A substring of 11 should return all IDs from 1-9.

Can anyone recommend a concise way to achieve this? Or provide a better data structure for retrieving this information?

like image 427
LeopardSkinPillBoxHat Avatar asked Oct 19 '11 04:10

LeopardSkinPillBoxHat


People also ask

How to perform partial match string in Excel?

If you want to perform a partial matching string, the most straightforward solution is to use wildcards. Excel has many options like VLOOKUP, XLOOKUP, INDEX with MATCH, combining IF with other functions to perform this task. Today we will learn how to Perform Partial Match String in Excel. 1. IF OR Statements to Perform Partial Match String 2.

How do I search for multiple partial strings in SQL Server?

Note that we can use the | operator to search for as many partial strings as we’d like. The following code shows how to use this operator to return the rows with partial strings ‘A’, ‘C’, ‘D’, ‘F’, or ‘G’ in the player column:

How to find names that contain one of the text strings?

We need to identify the names that contain one of the text strings given in columns 2 and 3. That means we need to find out the names that include the letter “A” or “L”. On the “Status” column in cell “E4”, apply the IF OR formula. The format of this formula is, Insert the values into the formula. The final formula for the partial match is

What is the use of DICT and filter function in Python?

In this, the dict and filter function is used to convert the result to dictionary and query for the substring in list respectively. The lambda performs the task of accessing all key-value pairs.


1 Answers

I would do an extension method :

public static class DictionaryExt
{
    public static IEnumerable<T> PartialMatch<T>(this Dictionary<string, T> dictionary, string partialKey)
    {
        // This, or use a RegEx or whatever.
        IEnumerable<string> fullMatchingKeys = 
            dictionary.Keys.Where(currentKey => currentKey.Contains(partialKey));

        List<T> returnedValues = new List<T>();

        foreach (string currentKey in fullMatchingKeys)
        {
            returnedValues.Add(dictionary[currentKey]);
        }

        return returnedValues;
    }
}

The "cost" of adding values to the dictionary wouldn't change, but the cost of retrieval would be higher, but only when you know you're going with a partial match.

Btw, I'm sure you could transform this in a single Lambda expression, but the concept remains the same.

Edit: In your example, this method would return 2 lists of values, but you can change it to merge the lists. Here is the extension method you could do :

public static IEnumerable<T> PartialMatch<T>(
    this Dictionary<string, IEnumerable<T>> dictionary,
    string partialKey)
{
    // This, or use a RegEx or whatever.
    IEnumerable<string> fullMatchingKeys = 
        dictionary.Keys.Where(currentKey => currentKey.Contains(partialKey));

    List<T> returnedValues = new List<T>();

    foreach (string currentKey in fullMatchingKeys)
    {
        returnedValues.AddRange(dictionary[currentKey]);
    }

    return returnedValues;
}

Edit 2: Come to think of it, you could also make it more generic. With the next extension method, it would work on any dictionary, as long as you provide a comparer that check what you mean by "partial match" :

public static IEnumerable<TValue> PartialMatch<TKey, TValue>(
    this Dictionary<TKey, IEnumerable<TValue>> dictionary,
    TKey partialKey,
    Func<TKey, TKey, bool> comparer)
{
    // This, or use a RegEx or whatever.
    IEnumerable<TKey> fullMatchingKeys = 
        dictionary.Keys.Where(currentKey => comparer(partialKey, currentKey));

    List<TValue> returnedValues = new List<TValue>();

    foreach (TKey currentKey in fullMatchingKeys)
    {
        returnedValues.AddRange(dictionary[currentKey]);
    }

    return returnedValues;
}
like image 157
Tipx Avatar answered Oct 16 '22 05:10

Tipx