PC Review


Reply
Thread Tools Rate Thread

get original key object from dictionary

 
 
not_a_commie
Guest
Posts: n/a
 
      14th Dec 2007
given a Dictionary<object, object> and an object that exactly
replicates the Equals and GetHashCode of the original object used as
the dictionary key, how do I retrieve the original key that was used?
 
Reply With Quote
 
 
 
 
Marc Gravell
Guest
Posts: n/a
 
      14th Dec 2007
I can't see an easy way - perhaps you have to drop down to looping?
Shown in the general (TKey / TValue) terms:

TKey testKey; // our equivalent but different key

IEqualityComparer<TKey> comparer = dict.Comparer;
foreach (KeyValuePair<TKey, TValue> pair in dict) {
if (comparer.Equals(testKey, pair.Key)) {
return pair.Key; // the original (or a clone if
blittable)
}
}
throw new KeyNotFoundException();

Marc
 
Reply With Quote
 
 
 
 
Peter Bromberg [C# MVP]
Guest
Posts: n/a
 
      14th Dec 2007
Not sure I understand the objective here. If you used the ContainsKey method
and it returns true, you know you have it, correct?
-- Peter
Site: http://www.eggheadcafe.com
UnBlog: http://petesbloggerama.blogspot.com
MetaFinder: http://www.blogmetafinder.com


"not_a_commie" wrote:

> given a Dictionary<object, object> and an object that exactly
> replicates the Equals and GetHashCode of the original object used as
> the dictionary key, how do I retrieve the original key that was used?
>

 
Reply With Quote
 
Marc Gravell
Guest
Posts: n/a
 
      14th Dec 2007
> Not sure I understand the objective here. If you used the ContainsKey method
> and it returns true, you know you have it, correct?


I believe the OP means that he has two different objects (presumably
classes) that he considers equal - i.e. they represent the same
Customer, but are different instances. He intends to use the one he
has "in hand" to find the original that was used as the key in the
dictionary. Quite common when dealing with facades, flyweights, etc.

I have seen this done before, but I think I've concluded over the
years that I prefer to use primatives for keys...

Marc
 
Reply With Quote
 
Peter Duniho
Guest
Posts: n/a
 
      14th Dec 2007
On Fri, 14 Dec 2007 14:16:42 -0800, Marc Gravell <(E-Mail Removed)>
wrote:

>> Not sure I understand the objective here. If you used the ContainsKey
>> method
>> and it returns true, you know you have it, correct?

>
> I believe the OP means that he has two different objects (presumably
> classes) that he considers equal - i.e. they represent the same
> Customer, but are different instances. He intends to use the one he
> has "in hand" to find the original that was used as the key in the
> dictionary. Quite common when dealing with facades, flyweights, etc.


But doesn't Dictionary<> already handle that correctly?

Obviously for value types as keys, it does. But AFAIK it also does as
well for reference types. For example, if the key is a string, as long as
I have a string instance that is equal to the one used for the key, it
does not have to be the same string instance as that originally used as
the key.

What's in the class shouldn't matter, as long as it hashes and compares
the same as the original key.

I share Peter B.'s confusion over the question. Seems like given what the
OP's already stated, the Dictionary<> does just what he'd want, without
additional work. Either he's missing something, or Peter and I are.

Pete
 
Reply With Quote
 
Nicholas Paldino [.NET/C# MVP]
Guest
Posts: n/a
 
      15th Dec 2007
I think that the OP has an instance of a type which has other members
which don't necessarily contribute to the identity of the object being used
as a key, and he needs to retrieve those from the original key.

Which I agree really doesn't make sense, because if it is that
important, those attributes should be stored elsewhere, based on the same
key.

--
- Nicholas Paldino [.NET/C# MVP]
- (E-Mail Removed)

"Peter Duniho" <(E-Mail Removed)> wrote in message
news(E-Mail Removed)...
> On Fri, 14 Dec 2007 14:16:42 -0800, Marc Gravell <(E-Mail Removed)>
> wrote:
>
>>> Not sure I understand the objective here. If you used the ContainsKey
>>> method
>>> and it returns true, you know you have it, correct?

>>
>> I believe the OP means that he has two different objects (presumably
>> classes) that he considers equal - i.e. they represent the same
>> Customer, but are different instances. He intends to use the one he
>> has "in hand" to find the original that was used as the key in the
>> dictionary. Quite common when dealing with facades, flyweights, etc.

>
> But doesn't Dictionary<> already handle that correctly?
>
> Obviously for value types as keys, it does. But AFAIK it also does as
> well for reference types. For example, if the key is a string, as long as
> I have a string instance that is equal to the one used for the key, it
> does not have to be the same string instance as that originally used as
> the key.
>
> What's in the class shouldn't matter, as long as it hashes and compares
> the same as the original key.
>
> I share Peter B.'s confusion over the question. Seems like given what the
> OP's already stated, the Dictionary<> does just what he'd want, without
> additional work. Either he's missing something, or Peter and I are.
>
> Pete


 
Reply With Quote
 
Marc Gravell
Guest
Posts: n/a
 
      15th Dec 2007
> I share Peter B.'s confusion over the question. Seems like given what the
> OP's already stated, the Dictionary<> does just what he'd want, without
> additional work. Either he's missing something, or Peter and I are.


The original question was (my emph): "how do I retrieve the original
****key**** that was used?"

Using an alternative but equivalent *key* will allow you to get the
same *value*, but it won't (unless I'm being really slow) allow you
direct access to the original *key*.

My interpretation of the question, therefore, is: in the following,
and given you know only "dict" and "equivalentKey", obtain the
instance "originalKey".
The loop I provided whould do this.

Dictionary dict = ...
MyKey originalKey = ...
MyValue value = ...

dict.Add(originalKey, value);
MyKey equivalentKey = originalKey.Clone();
 
Reply With Quote
 
Peter Duniho
Guest
Posts: n/a
 
      15th Dec 2007
On Fri, 14 Dec 2007 14:16:42 -0800, Marc Gravell <(E-Mail Removed)>
wrote:

>> Not sure I understand the objective here. If you used the ContainsKey
>> method
>> and it returns true, you know you have it, correct?

>
> I believe the OP means that he has two different objects (presumably
> classes) that he considers equal - i.e. they represent the same
> Customer, but are different instances.


For the record, I wrote a small sample program (see below) that confirms
to the OP requirements as I understand them, and without anything extra it
"just works". I don't even have to use the same type or even a related
type when calling ContainsKey() as that used for the actual key.

I think some clarification is in order, if there's something OP is trying
to do but can't.

Pete


using System;
using System.Collections.Generic;
using System.Text;

namespace TestCustomHashDictionary
{
class Program
{
class TestClassOne
{
private string _str1;
private string _str2;

public TestClassOne(string str1, string str2)
{
_str1 = str1;
_str2 = str2;
}

public override int GetHashCode()
{
return _str1.GetHashCode() ^ _str2.GetHashCode();
}

public override bool Equals(object obj)
{
if (obj != null)
{
return ToString().Equals(obj.ToString());
}

return false;
}

public override string ToString()
{
return _str1 + _str2;
}
}

class TestClassTwo
{
private string _str;
private int _hash;

public TestClassTwo(string str1, string str2)
{
_hash = str1.GetHashCode() ^ str2.GetHashCode();
_str = str1 + str2;
}

public override int GetHashCode()
{
return _hash;
}

public override bool Equals(object obj)
{
return ToString().Equals(obj.ToString());
}

public override string ToString()
{
return _str;
}
}

static void Main(string[] args)
{
Dictionary<object, object> dict = new Dictionary<object,
object>();

dict.Add(new TestClassOne("one", "two"), null);

Console.WriteLine(
"dict.ContainsKey(new TestClassTwo(\"one\", \"two\"): "
+ dict.ContainsKey(new TestClassTwo("one", "two")));

Console.ReadLine();
}
}
}
 
Reply With Quote
 
Peter Duniho
Guest
Posts: n/a
 
      15th Dec 2007
On Fri, 14 Dec 2007 15:10:01 -0800, Marc Gravell <(E-Mail Removed)>
wrote:

> The original question was (my emph): "how do I retrieve the original
> ****key**** that was used?"
>
> Using an alternative but equivalent *key* will allow you to get the
> same *value*, but it won't (unless I'm being really slow) allow you
> direct access to the original *key*.


No, I think I was being slow. I didn't pick up the fact that he wanted
the original key.

While I agree with Nicholas that this may indicate a problem with the
basic design of the OP's code, it does highlight something that's bugged
me about the Dictionary<> and similar classes. That is, you can get a
collection of keys that is ordered (even if the order isn't well-defined),
and you can check for containment of a key, but you cannot get the ordinal
index of that key related to the collection, given the key.

Obviously the class itself has a fast way to do that, but it doesn't
expose it in any way as far as I know. I've seen at least two different
situations now where it'd be useful (this scenario, and a previous thread
that involved the fastest way to get an item from a Dictionary).

Anyway, thanks for the clarification. I understand the OP now (and the
misunderstanding was all mine...rereading the post, it seems fine ).

Pete
 
Reply With Quote
 
Marc Gravell
Guest
Posts: n/a
 
      15th Dec 2007
> ... something that's bugged me about the Dictionary<> and similar classes
> ... but you cannot get the ordinal index of that key related to the collection, given the key.


Well, you can for SortedList, but that's about it... ;-(

Marc
 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Dictionary with object for key Luigi Microsoft C# .NET 2 4th Nov 2008 02:58 PM
Dictionary<TKey,TValue> as a Dictionary key in C# 2.0 dox Microsoft Dot NET 5 19th Mar 2008 03:15 PM
Where can I get a dictionary to add into my custom dictionary in . =?Utf-8?B?TmVpbCBCcmV0dA==?= Microsoft Word Document Management 1 13th Oct 2004 03:48 PM
dictionary with multiple object under the same key Maersa Microsoft Dot NET Framework 4 1st Dec 2003 06:12 AM
How To Get The Original IE URL or Word's Original filepath? Lex Yacc Microsoft C# .NET 0 7th Aug 2003 04:21 AM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 05:31 AM.