473,385 Members | 1,620 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Want a key value collection that maintains ordering

Hi all, is there a key value collection in .Net that maintains the
ordering in which I add items.

I'm finding that I'm creating a number of classes that contain a name
and then some object. I would prefer just to use some collection that
maintains the ordering in which I add things (like ArrayList), but that
maps a key to a value.

I thought NameValueCollection was the right one - but it doesn't
guarantee ordering.

If it doesn't exist, why not? If it doesn't what is the "right" way to
build it? Just have wrap your class around an instance of ArrayList
and have some internal class that takes the key given in the Add method
and instantiates this generic class with two members (a string key and
an object value), then add that to the internal ArrayList?

Thanks,
Novice

May 2 '06 #1
23 11237
I would create a class that wraps an ArrayList and a Hashtable.
Whenever anything is added to your class, add it to both the ArrayList
and the Hashtable. When you want to return an iterator, return an
iterator into the ArrayList. When you want a lookup by key, look it up
in the Hashtable.

May 2 '06 #2
I was actually thinking of doing something like that originally since
it is all reference based, there would be minimal cost (memory) to do
something like that - i.e. to have the ArrayList and the Hashtable to
point to the various elements.

Does anyone know of any reason why I should just rip off the
implementation of PhoneNumberDictionary (that extends DictionaryBase)
from here:
http://www.codeproject.com/csharp/collection1.asp

I'm not doing a PhoneNumberDictionary, but it seems to provide what I
want in terms of allowing me to specify an arbitrary name and an
arbitrary object. And when I get them all, they will be returned in
the order I added them.

Does that sound right?

Thanks,
Novice

May 3 '06 #3
Crud!

I've tried using DictionaryBase, but the compiler gives me
DictionaryBase could not be found. I guess that means it is a .Net 2
class?

That sucks.

May 3 '06 #4
Never mind - looks like the executable wasn't getting regenerated or
something - fresh build and the compiler was okay with it.

May 3 '06 #5
Well, this doesn't work, it doesn't maintain the order in which I added
them when I iterate through it.

So I guess I will just do something like (not compileable code):
class DictionaryEntryCollection
{
private ArrayList mKeyValues;

public DictionaryEntryCollection()
{
mKeyValues = new ArrayList();
}

public void Add (object key, object value)
{
DictionaryEntry keyValue = new DictionaryEntry(key, value);
mKeyValues.Add(keyValue);
}

public DictionaryEntry[] GetKeyValueElements()
{
//iterate over all the elements in my arraylist
}
}

Sound right?

Thanks,
Novice

May 3 '06 #6
Bruce Wood wrote:
I would create a class that wraps an ArrayList and a Hashtable.
Whenever anything is added to your class, add it to both the ArrayList
and the Hashtable. When you want to return an iterator, return an
iterator into the ArrayList. When you want a lookup by key, look it up
in the Hashtable.


What if you add something with the same key twice? It will show up in
the hashtable just once but in the ArrayList twice. That is probably
not what he's looking for.

I'd create a new collection that wrapped an ArrayList<Object[]> and
massage the add method to check for duplicates, while maintaining order.

I just whipped something up in Java. Its untested, unsynchronized,
probably slow, and the syntax is slightly different for C# (the for
loop). Here it is; it might help you, it might not.

public class HashList {

private ArrayList<Object[]> coll;

public HashList() {
coll = new ArrayList<Object[]>();
}

public void add(Object key, Object value) {
boolean alreadyAdded = false;

for (Object[] s : coll) {
if (s[0] == key) {
int me = coll.indexOf(s);
coll.remove(me);
coll.add(me, s);
alreadyAdded = true;
}
}

if (!alreadyAdded) {
coll.add(new Object[] { key, value });
}
}

}
May 3 '06 #7
Novice,

You can just use the SortedList<TKey, TValue> generic class. It will
allow you to perform lookups, and order the list as well.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

<il***********@gmail.com> wrote in message
news:11**********************@j73g2000cwa.googlegr oups.com...
Hi all, is there a key value collection in .Net that maintains the
ordering in which I add items.

I'm finding that I'm creating a number of classes that contain a name
and then some object. I would prefer just to use some collection that
maintains the ordering in which I add things (like ArrayList), but that
maps a key to a value.

I thought NameValueCollection was the right one - but it doesn't
guarantee ordering.

If it doesn't exist, why not? If it doesn't what is the "right" way to
build it? Just have wrap your class around an instance of ArrayList
and have some internal class that takes the key given in the Add method
and instantiates this generic class with two members (a string key and
an object value), then add that to the internal ArrayList?

Thanks,
Novice

May 3 '06 #8
Nicholas,

new to Generics, is SortedList already generic?

Why can I ! say SortedList<string,string> ??? Throws Error
if (!Page.IsPostBack)
{
AlwaysSortedList = new SortedList();
Session.Add("ASL",AlwaysSortedList);
}

in button handler....

((SortedList)Session["ASL"]).Add(TextBox1.Text,TextBox1.Text);
DropDownList1.DataSource = ((SortedList)Session["ASL"]); //AlwaysSortedList;
DropDownList1.DataTextField = "key";
DropDownList1.DataValueField = "value";
DropDownList1.DataBind();

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:%2******************@TK2MSFTNGP04.phx.gbl...
Novice,

You can just use the SortedList<TKey, TValue> generic class. It will
allow you to perform lookups, and order the list as well.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

<il***********@gmail.com> wrote in message
news:11**********************@j73g2000cwa.googlegr oups.com...
Hi all, is there a key value collection in .Net that maintains the
ordering in which I add items.

I'm finding that I'm creating a number of classes that contain a name
and then some object. I would prefer just to use some collection that
maintains the ordering in which I add things (like ArrayList), but that
maps a key to a value.

I thought NameValueCollection was the right one - but it doesn't
guarantee ordering.

If it doesn't exist, why not? If it doesn't what is the "right" way to
build it? Just have wrap your class around an instance of ArrayList
and have some internal class that takes the key given in the Add method
and instantiates this generic class with two members (a string key and
an object value), then add that to the internal ArrayList?

Thanks,
Novice


May 3 '06 #9
Yes. In VB 2005, you would use

dim AlwaysSortedList as new SortedList(of String, String)
AlwaysSortedList.add("Key1", "This is Key1")

debug.print(AlwaysSortedList("Key1") displays "This is Key1" in the
Immediate window.

Mike Ober.

"MSDN" <sq**********@hotmail.com> wrote in message
news:eh**************@TK2MSFTNGP04.phx.gbl...
Nicholas,

new to Generics, is SortedList already generic?

Why can I ! say SortedList<string,string> ??? Throws Error
if (!Page.IsPostBack)
{
AlwaysSortedList = new SortedList();
Session.Add("ASL",AlwaysSortedList);
}

in button handler....

((SortedList)Session["ASL"]).Add(TextBox1.Text,TextBox1.Text);
DropDownList1.DataSource = ((SortedList)Session["ASL"]); //AlwaysSortedList; DropDownList1.DataTextField = "key";
DropDownList1.DataValueField = "value";
DropDownList1.DataBind();

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in message news:%2******************@TK2MSFTNGP04.phx.gbl...
Novice,

You can just use the SortedList<TKey, TValue> generic class. It will
allow you to perform lookups, and order the list as well.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

<il***********@gmail.com> wrote in message
news:11**********************@j73g2000cwa.googlegr oups.com...
Hi all, is there a key value collection in .Net that maintains the
ordering in which I add items.

I'm finding that I'm creating a number of classes that contain a name
and then some object. I would prefer just to use some collection that
maintains the ordering in which I add things (like ArrayList), but that
maps a key to a value.

I thought NameValueCollection was the right one - but it doesn't
guarantee ordering.

If it doesn't exist, why not? If it doesn't what is the "right" way to
build it? Just have wrap your class around an instance of ArrayList
and have some internal class that takes the key given in the Add method
and instantiates this generic class with two members (a string key and
an object value), then add that to the internal ArrayList?

Thanks,
Novice




May 3 '06 #10
I can't use .Net 2 yet... I'm stuck with my current version of .Net -
but thanks for the suggestion none the less.

Novice

May 3 '06 #11
But the OP asked that the entries be maintained in their original
order, not in key order. That's why I didn't suggest SortedList.

May 3 '06 #12
Why not add a Hashtable to that and avoid the iteration over the
ArrayList looking for the item? A linear search is terribly slow.

May 3 '06 #13
> What if you add something with the same key twice? It will show up in
the hashtable just once but in the ArrayList twice. That is probably
not what he's looking for.


There's a simple solution to that:

public void Add(object key, object item)
{
object existingItem = this._hash[key];
if (existingItem != null)
{
this._array.Remove(existingItem);
}
this._hash[key] = item;
this._array.Add(item);
}

Much better than doing a linear search every time you add an item.

If the OP wants instead a collection that permits duplicates (two items
with the same key) then it's no longer clear what the indexer should
return.

May 3 '06 #14
Novice,

Bruce's idea is really the best one IMO. Here's a link to an
implementation.

<http://www.codeproject.com/csharp/keyedlist.asp#xx701821xx>

Brian

il***********@gmail.com wrote:
Hi all, is there a key value collection in .Net that maintains the
ordering in which I add items.

I'm finding that I'm creating a number of classes that contain a name
and then some object. I would prefer just to use some collection that
maintains the ordering in which I add things (like ArrayList), but that
maps a key to a value.

I thought NameValueCollection was the right one - but it doesn't
guarantee ordering.

If it doesn't exist, why not? If it doesn't what is the "right" way to
build it? Just have wrap your class around an instance of ArrayList
and have some internal class that takes the key given in the Add method
and instantiates this generic class with two members (a string key and
an object value), then add that to the internal ArrayList?

Thanks,
Novice


May 3 '06 #15
So in case anyone is interested I did something even more simple than
Bruce's idea. I.E. I just wrapped ArrayList. The reason I don't also
use Hashtable is two fold:
1. My Collection also needs to be capable of containing other instances
of itself - i.e. I need a collection that can contain regular
key/value pairs, but any of those values could potentially be another
instance of itself. Therefore, I may end up with nested keys that are
identical - hence hashtable wouldn't work - unless I also embed
Hashtables in Hashtables - but that defeats the purpose of using
Hashtable for searching
2. Really just restating the last bit of point 1 - that is, a Hashtable
can't search on nested instances of itself - i.e. if I add a Hashtable
Object like this:
Hashtable hashtable = getHashtable1();
Hashtable hashtable2 = getHashtable2();
hashtable.Add("blah", hashtable2);

Now searching on hashtable2 won't be done.

However, after writing all that - perhaps I could come up with a clever
naming system, whereby nested instances get characters in them much
like folders/directories in the various OS'.

So I could use some illegal character for my names as a separator and
then search using that...

Hmm... that could work,
Novice

May 4 '06 #16
That's simple to solve. Use the data as the key. If you want to keep them
in the original order, any of the array list and collection objects will do
this by default - it's the way they're implemented.

Mike Ober.

"Bruce Wood" <br*******@canada.com> wrote in message
news:11**********************@g10g2000cwb.googlegr oups.com...
But the OP asked that the entries be maintained in their original
order, not in key order. That's why I didn't suggest SortedList.


May 4 '06 #17


jeremiah johnson wrote:
Bruce Wood wrote: I just whipped something up in Java. Its untested, unsynchronized,


Java have a LinkedHashMap (or something like that) which does exactly
what OP want's.

The "good" (TM :) solution is to store double-linked-lists with
insertion-order and let the values in the hash contain references to
their linked-list representation.

This allows O(1) insert,update and remove, as well as ordered traversal
(forward and backward) and is exactly what the correspoding JAVA class does.

--
Helge
May 4 '06 #18


Michael D. Ober wrote:
That's simple to solve. Use the data as the key. If you want to keep them
in the original order, any of the array list and collection objects will do
this by default - it's the way they're implemented.


IDictionary have no ordering, which was what OP wanted.

You *could* embed the ordering into the keys, and use SortedList, but I
don't like the idea of embedding collection-containment info into the
contained objects. For one thing each object can only be contained in
one such list.

A better alternative is to do linked-list-hashtables.

--
Helge
May 4 '06 #19


il***********@gmail.com wrote:
So in case anyone is interested I did something even more simple than
Bruce's idea. I.E. I just wrapped ArrayList. The reason I don't also
use Hashtable is two fold:
So you've chosen linear lookup-time.
1. My Collection also needs to be capable of containing other instances
of itself - i.e. I need a collection that can contain regular
key/value pairs, but any of those values could potentially be another
instance of itself. Therefore, I may end up with nested keys that are
identical - hence hashtable wouldn't work - unless I also embed
*Nested* identical keys shouldn't be a problem. They are contained in
separate data-structures.
Hashtables in Hashtables - but that defeats the purpose of using
Hashtable for searching
Well,... atleast in multiple layers. Why don't you just have
IDictionary'es, and then use a hashtable for the "big" ones and
something else for the "smaller" ones?
2. Really just restating the last bit of point 1 - that is, a Hashtable
can't search on nested instances of itself - i.e. if I add a Hashtable
Object like this:
Hashtable hashtable = getHashtable1();
Hashtable hashtable2 = getHashtable2();
hashtable.Add("blah", hashtable2);

Now searching on hashtable2 won't be done.
If you have a flat data-structure encoded in a recursive data-structure
(for performance) the recursion shouldn't be visible to the user.

If you have an inherently recursive data-structure you should probably
show that to the user, and do recursive lookup, and everything would be
fine.

What exactly is the type of your keys? which type are they? single:
"foo", or tupled: ("x", "y"), or list-like: ["x", "y", ...] ?
However, after writing all that - perhaps I could come up with a clever
naming system, whereby nested instances get characters in them much
like folders/directories in the various OS'.
Thats called linearization. Perhaps you *are* having a recursive
data-structure and you're just not doing lookup in a way corresponding
to that?

It sounds a lot like a tree with indexed children to me :)
So I could use some illegal character for my names as a separator and
then search using that...

Hmm... that could work,


Watch out, along that bumpy road lies all the dangers of linearization:

- escaping
- delinearization
- parsing, and error-handling of unparseable data
- formulation of searches

If your data *is* recursively structured, you are probably best off
storing the recursively and doing recursive lookups:

void object lookup(params object[] keys) {
IDictionary d = TopDict;
for ( int i = 0; i < keys.Length - 1; ++i )
d = (IDictionary)d[keys[i]];
return d[keys[keys.Length - 1]];
}

dict.lookup("foo", "foo", "baz");
--
Helge
May 4 '06 #20
Going back to your original post...
is there a key value collection in .Net that maintains the
ordering in which I add items. I would prefer just to use some collection that
maintains the ordering in which I add things (like ArrayList), but that
maps a key to a value.


So... this isn't exactly what you want after all. What you want is
something that maps a _multi-part_ key onto a value, or perhaps stores
values in a hierarchical structure but also in insertion order? Your
solution isn't "simpler" than mine... rather, it solves a different
problem.

Since your original post doesn't completely state your problem, could
you restate the problem so that we understand, completely, what it is
that you need to do?

May 4 '06 #21
I seem to have offended you - sorry for that.

I have always wanted the same thing, but you're right I could have
provided more details on what I want.

I still want a "key value collection in .Net that maintains the
ordering in which I add items. I would prefer just to use some
collection that maintains the ordering in which I add things (like
ArrayList), but that maps a key to a value."

However, this key value collection also needs to be able to hold a
hierarchy of collections. Therefore, the values need to be able to be
traversed - since they values could themselves be key value
collections.

I have a working solution, if not an efficient one. I'm just surprised
that short of getting .Net 2 there is no generic solution.

Thanks,
Novice

May 4 '06 #22
Don't worry. You didn't offend me. I was just pointing out that your
requirements seemed to have changed, in hopes of getting more details.

Your solution may be efficient enough if there are few elements in your
collection. If there are very many, though, you may want to implement
Brian Gideon's class and then just use a hierarchy of them.

I don't believe that there's a generic solution even in .NET 2.0
(unless I missed something in the conversation). Yours isn't a very
common requirement: most people want either a straight hash or a
_sorted_ list of items with quick access by key.

May 5 '06 #23

Bruce Wood wrote:
Your solution may be efficient enough if there are few elements in your
collection. If there are very many, though, you may want to implement
Brian Gideon's class and then just use a hierarchy of them.


I should give credit where credit is due. It isn't actually my class.
Someone else wrote that article :)

May 5 '06 #24

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: m. pollack. | last post by:
Hi all, Is there any information to be had about the "Object Collection Editor" that appears when you click on a collection property in the PropertyGrid control? I have a class that maintains a...
15
by: keweiming | last post by:
I have a project which needs to open hundreds to thousands of files for writing. The following is a simplified test program I wrote to see if I can use a map<string, ofstream> object to keep the...
9
by: Project2501a | last post by:
hey guys, Question about the internal workings of Access. How are controls added in the Form.Controls collection? I mean, in which order? the order place them on the form? is there a way to...
5
by: Frank | last post by:
Our system maintains session state using the ASP.NET State Server service. We expect some of our session state objects to be over 85K, which categorizes them to be VLO's (very large objects) in terms...
3
by: marcuslm | last post by:
I need help figuring out which collection to use. Maybe I need to create my own but here's what I need. A collection that... 1. provides ability to access values via a key 2. maintains the...
9
by: Michael D. Ober | last post by:
In the code below, the IComparator function is never called. What am I missing? Public Class ArchiveInfo Implements System.IComparable(Of ArchiveInfo) Public FullName As String = "" Public...
26
by: Martin R | last post by:
Hi, How to find first not null value in column whitout chacking whole table (if there is a not null value then show me it and stop searching, the table is quite big)? thx, Martin *** Sent...
1
by: evanburen | last post by:
When my page loads, I check for the existence of a cookie value through readCookie(). If there is a value present for the cookie, I would like that to be the default value in function ordering()...
2
by: zephyr | last post by:
Hi, I have a hidden field in my form: <input type="hidden" name="checkBoxesCollection" value=""> If I submit the form I call a javascript function: function storeCheckboxFieldNames(theForm){...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.