Jump to content
  • Advertisement
Sign in to follow this  
Toolmaker

[.net] .NET dictionary with (string) key completion?

This topic is 3310 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm currently looking for a .NET dictionary which uses strings for keys, and offers the ability to auto-complete the string keys. The kind of behaviour I would like to achieve is somewhat like this: If I add 2 keys to the dictionary, says 'apple' and 'cherry', and I want to look up a value in the dictionary, that it would work if I supplied a partial key, as in 'app', which would auto complete to 'apple', and return the value stored with the key. Right now, if I want to achieve this kind of behavior I need to add all variations to the dictionary, which technically would work, but requires a lot of additional work for me since these dictionaries change regularly. Toolmaker

Share this post


Link to post
Share on other sites
Advertisement
There's probably a better way that this, but I'd just use C++/CLI to expose an instance of cliext::map<> with a string key. When you need to check for a partial key use lower_bound().

Share this post


Link to post
Share on other sites
If I understood correctly, you want something akin to this


var strings = new Dictionary<string, string>{{"ABC", "1"}, {"DEF", "2"}, {"GHI", "3"}, {"JKL", "4"}, {"A2", "5"}, {"D2", "6"}, {"G2", "7"}, {"J2", "3"}};

var result = from s in strings
where s.Key.StartsWith("A")
select s.Value;

result.ToList().ForEach(Console.WriteLine);





I believe internally StartsWith behaves like the solution described by SiCrane.

(If strings was a list, the query would be just

var result = from s in strings where s.StartsWith("A") select s;
result.ToList().ForEach(Console.WriteLine);



)


[Edited by - Naurava kulkuri on June 18, 2009 8:04:25 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
There's probably a better way that[sic] this, but I'd just use C++/CLI to expose an instance of cliext::map<> with a string key. When you need to check for a partial key use lower_bound().


There is actually a much better way to do this [grin]

Dictionary (and a few other collections) allow you to specify an implementation of IEqualityComparer, which you can easily override to allow any sort of key matching function you want. Naurava kulkuri's approach will work for this specific example, but the equality comparer method will be used throughout the Dictionary's methods.

While you could just derive a new class from IEqualityComparer each time, I prefer using the following generic class so that you can specify the comparison method inline using lambdas/anonymous delegates. Your mileage may vary.

class InlineComparer<T> : IEqualityComparer<T>
{
readonly Func<T, T, bool> equals;
readonly Func<T, int> getHashCode;

public StuffComparer(Func<T, T, bool> equals, Func<T, int> getHashCode)
{
this.equals = equals;
this.getHashCode = getHashCode;
}

public bool Equals(T x, T y)
{
return equals(x, y);
}

public int GetHashCode(T obj)
{
return getHashCode(obj);
}
}



The solution to your example then becomes:

var dictionary = new Dictionary<string, string>(new InlineComparer<string>(
(s1, s2) => s1.StartsWith(s2),
s => s.GetHashCode()
));

// use however you want

Share this post


Link to post
Share on other sites
How does this work when there are multiple keys matching the queried key? It seems that you'd just get one of the matching items at random to me.

Share this post


Link to post
Share on other sites
Quote:
Original post by Mike.Popoloski
There is actually a much better way to do this [grin]

Doesn't that violate the conditions for IEqualityComparer? The equality condition isn't symmetric or transitive, and Equals(x, y) doesn't imply GetHashCode(x) == GetHashCode(y).

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Quote:
Original post by Mike.Popoloski
There is actually a much better way to do this [grin]

Doesn't that violate the conditions for IEqualityComparer? The equality condition isn't symmetric or transitive, and Equals(x, y) doesn't imply GetHashCode(x) == GetHashCode(y).


Yeah, I realized that a little while ago. I wonder if it would work if you just did s1.StartsWith(s2) || s2.StartsWith(s1)

EDIT: Just did a little more reading, and obviously no this will not work. Ignore me completely [grin]

Share this post


Link to post
Share on other sites
Quote:
Original post by Mike.Popoloski
EDIT: Just did a little more reading, and obviously no this will not work. Ignore me completely [grin]
I'm not sure what you were after, but there's a similar kind of an approach discussed at Stack Overflow. Related to this this on implementing a generic comparer in C# (and .NET). I'm guessing your idea was related to this, but in any case, a few quick links to follow if someone is pondering over these and feels puzzled what it could be. :)

On a related note, there's a rather neat way on implementing a generic INotifyPropertyChanged system with ideas related to these. Very short and to the point.

Share this post


Link to post
Share on other sites
I would search around to see if anyone has already written a Trie for .Net (which they probably have).

A Trie is exactly what you want if you intend to use the autocompletion primarily instead of the string hash primarily as the lookup method.

Share this post


Link to post
Share on other sites
Quote:
Original post by Nypyren
I would search around to see if anyone has already written a Trie for .Net (which they probably have).

A Trie is exactly what you want if you intend to use the autocompletion primarily instead of the string hash primarily as the lookup method.


That's an interesting one... Currently I use a list with the linq selection statement. It works, but I'm not sure if it's fast enough in the future. But it'll has to prove itself.

Toolmaker

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!