Generic dictionary

M

Michaelov, Itzik

Dictionary have strange behavior.
A need always add entry at end of collection, but it doesn't work
The following is my source:

Dictionary<string, string> a = new Dictionary<string, string>();

a.Add("3", "3");
a.Add("i3", "i3");
a.Add("2i3", "2i3");

a.Remove("3");

a.Add("i2", "i2");


Please notice that last source row("i2", "i2") add element to first place
instead removed item("3", "3")
Maybe i need use another collection type ?!

Thanks a lot
 
W

Willem van Rumpt

Dictionary have strange behavior.
A need always add entry at end of collection, but it doesn't work
The following is my source:

Dictionary<string, string> a = new Dictionary<string, string>();

a.Add("3", "3");
a.Add("i3", "i3");
a.Add("2i3", "2i3");

a.Remove("3");

a.Add("i2", "i2");

The generic Dictionary<T, K> does not have a concept of a begin or an
end, and cannot be accessed by index. AFAIK, there's no existing
framework class that lets you store key-value pairs *and* have control
over the insertion point, but rolling your own shouldn't be too difficult.
 
H

Harlan Messinger

Dictionary have strange behavior.
A need always add entry at end of collection, but it doesn't work
The following is my source:

Dictionary<string, string> a = new Dictionary<string, string>();

a.Add("3", "3");
a.Add("i3", "i3");
a.Add("2i3", "2i3");

a.Remove("3");

a.Add("i2", "i2");


Please notice that last source row("i2", "i2") add element to first
place instead removed item("3", "3")
Maybe i need use another collection type ?!

A Dictionary has no defined order. Its primary purpose is to provide
direct access to values associated with keys, and to do that efficiently
it stores the entries in a manner that is different from an ordered
list. Ordinarily when a Dictionary is enumerated, it is desirable to
sort it in some logical way according to the keys, not in the order of
entry.

If you have a real need to retrieve the data in the order in which it
was stored, there is a non-generic OrderedDictionary class, which I
imagine stores its entries in a list AND also maintains an implicit hash
table or tree structure for dictionary-style look-up purposes.
 
P

Peter Duniho

Willem said:
The generic Dictionary<T, K> does not have a concept of a begin or an
end,
True.

and cannot be accessed by index.

Mostly true. However, note that you can get the Keys and Values
collections from a Dictionary, and can index those collections (but they
are in enumeration order for the Dictionary, which of course is not
insertion order).
AFAIK, there's no existing
framework class that lets you store key-value pairs *and* have control
over the insertion point, but rolling your own shouldn't be too difficult.

Depending on the specific needs, a SortedDictionary _could_ work. It'd
be a pretty specialized situation though.

A parallel data structure, where there's both a dictionary and a simple
list, would be one approach. Alternatively, if you don't need frequent
access to the data in insertion order, you could create a simple key
type that stores both the key and the order of insertion, which you can
then use as the actual key:

struct OrderedKey<T>
{
public T Key { get; private set; }
public int Order { get; private set; }

public OrderedKey(T key, T order)
{
Key = key;
Order = order;
}

public override bool Equals(object obj)
{
if (object.ReferenceEquals(this, obj))
{
return true;
}

OrderedKey<T> t = obj as OrderedKey<T>;

if (t == null)
{
return false;
}

return Key.Equals(t.Key);
}

public override int GetHashCode()
{
return Key.GetHashCode();
}
}

Or something like that. Of course, you'd have to track the insertion
order somehow, such as having a counter in the code where the dictionary
is populated.

With that in hand, you can then enumerate the dictionary in insertion
order as needed:

Dictionary<OrderedKey<string>, DataType> dict = ...;

// dict initialized as needed

foreach (var kvp in dict.OrderBy(x => x.Key.Order))
{
// do something with kvp.Key.Key and/or kvp.Value
}

Finally, I'll note that _in general_, needing to maintain a collection
of objects in both an "order of insertion" and "indexed by key" should
be an unusual situation. I won't say it never comes up, but when
presented with something that looks like you need a solution like that,
I think the first thing to do is double-check your design and make sure
you really need to do that.

Pete
 
W

Willem van Rumpt

Peter said:
Depending on the specific needs, a SortedDictionary _could_ work. It'd
be a pretty specialized situation though.

And that's the reason I didn't want to go there ;)

In the case of a highly specialized situation, I think I'd prefer to go
for a highly specialized collection, instead of contorting collection
items into fitting a generic collection, but without knowing the
requirements, that's just speculation on my part.

So, true, it could work, and maybe it's enough for the OP.
 
H

Helmut Giese

Hi Michaelov
Dictionary have strange behavior.
as others have noted the sequence of adding entries to a dictionary
bears no relation to retrieving them.
If you use a generic KeyValuePair for the entries you can then build a
List or an Array of those and they will respect order of creation. Of
course you will lose the feature to access any entry by its key - you
will have to do the searching yourself.
HTH
Helmut Giese
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top