How can I create a 2D ArrayList? String usually.

  • Thread starter Thread starter Dan V.
  • Start date Start date
D

Dan V.

I would like to create a 2D string list (2D ArrayList ???). I would like to
pass in a table or query as a parameter and have both columns transform into
a 2D ArrayList. When I sort the one 'column' in the ArrayList, the other is
automatically sorted and so I can use IndexOf without fear. This is because
I will be going through 20,000 some odd records and don't want to use a
Lookup type of table/query; I figure an ArrayList.IndexOf method is faster.
 
I don't think that you can use the ArrayList class for a rank 2 array - it
only seems to manage a single dimensional array. For what it's worth, the
DataRowCollection uses an arraylist for its underlying storage (based on
what I've seen in Reflector).

I'm not entirely sure that I understand what you are after, but you might
try using the Select() method on the datatable -- I believe that it uses
some built-in indexing to return rows. Or, if what you are doing is more
custom than that, you might experiment with using a HashTable rather than
using Array.IndexOf.

Array.IndexOf is probably going to yield linear performance as you add items
to the array (unless you are doing sorting/binary searches). However, a
HashTable yields sublinear performance. I was load testing a
NameObjectCollectionBase derivitiave (which uses a HashTable under the
covers) for some performance testing, and found that it made virtually no
difference in avg lookup time between a collection of 100,000, and 1,000,000
members (avg time on my machine with 1,000,000 entries in a
NameObjectCollect -- basically a HashTable -- was around 0.0000013 seconds
per access).

Which is better (HashTable vs. DataTable.Select()) probably depends upon how
you are doing your searches. If you load up your datatable first, and then
search, I would guess (but it is a guess) that you could get by with
DataTable.Select. However, if you are searching as you load (duplicate
checks or something), you might be better off using hashtables. When we
were doing testing, we found that the datatable indexes seem to be rebuilt
any time you do a select after an add, so add | select | add | select,
wasn't a great option for some dup checking algorithm that someone here was
working on.
 
Thanks for the informative reply.
I basically would like a 2 column array or whatever that will be static, as
in values won't change after I load them and I would like to fairly quickly
search for a value in either column and either: 1. See if the value exists
or 2. get the value in the other column. I like the features of ArrayList
where you can add info easily initially and use IndexOf to quickly find if
value exists and if it does to get the other value. Basically something
faster than a DataTable and a query everytime. A Hash table would be
overkill for me at this point.
 
Similar to my reply, Is there a faster / better method: With one key
difference; What about if I only lookup in the first column to find the
value in the 2nd column, as opposed to searching either column?

"I basically would like a 2 column array or whatever that will be static, as
in values won't change after I load them and I would like to fairly quickly
search for a value in -ONLY THE FIRST- column and either: 1. See if the
value exists or 2. get the value in the other column...."
 
If you are only looking up the first column, so you have like a key-value
relationship, I would lean pretty heavily towards either the HashTable, the
StringDictionary, or the NameObjectCollectionBase. That's really what
they're made for, and the access is really fast.

The differences between them: A straight Hashtable accepts type object as
the key and returns type object as the value (so you can pass a string or
whatever as the key, and you will have to cast the value back:

myHashTable.Add("TheKey", aValue);
myType value = (myType)myHashTable["TheKey"];

A StringDictionary expects to be a list of string pairs, so that the add
method expects only strings:
myStringDictionary.Add("TheKey", "TheValue")
string value = myStringDictionar["TheKey"]

A NameObjectCollectionBase is an abstract class that you override to
customize it to your collection needs:
myNameObjectCollection.Add("TheKey", aValue);
myType value = myNameObjectCollection["TheKey"];

The benefit of the hashtable/dictionary is extremely speedy lookup.

Working where you want to access multiple columns is a little more
interesting. Right now, the only thing I have is brute force (2 hashtables,
swapping the key/value roles). We are actually have that issue as an "item
to solve" on the drawing board now, but we haven't gotten to it yet. If you
want, we can swap info on how to solve it as we discover. The downside is
that I expect it to be a couple of weeks before that particular item ends up
on anyone's plate over here.
 
The StringDictionary works great! Thanks.

I wish I could use code like this for Integers or strings in a DataReader.

MyStringDictionary.Add( rdr.GetString(0), rdr.GetString(1) )

It throws an exception if the first column is an Int32, so I have to know
the exact DataType and must resort to:

MyStringDictionary.Add( Convert.ToString(rdr.GetInt32(0)),
rdr.GetString(1) );

Aside: Now I could save a lot of code if I could find the DataType of a
column in the OleDbDataReader.
Using GetSchema is a bit slow.


J.Marsch said:
If you are only looking up the first column, so you have like a key-value
relationship, I would lean pretty heavily towards either the HashTable, the
StringDictionary, or the NameObjectCollectionBase. That's really what
they're made for, and the access is really fast.

The differences between them: A straight Hashtable accepts type object as
the key and returns type object as the value (so you can pass a string or
whatever as the key, and you will have to cast the value back:

myHashTable.Add("TheKey", aValue);
myType value = (myType)myHashTable["TheKey"];

A StringDictionary expects to be a list of string pairs, so that the add
method expects only strings:
myStringDictionary.Add("TheKey", "TheValue")
string value = myStringDictionar["TheKey"]

A NameObjectCollectionBase is an abstract class that you override to
customize it to your collection needs:
myNameObjectCollection.Add("TheKey", aValue);
myType value = myNameObjectCollection["TheKey"];

The benefit of the hashtable/dictionary is extremely speedy lookup.

Working where you want to access multiple columns is a little more
interesting. Right now, the only thing I have is brute force (2 hashtables,
swapping the key/value roles). We are actually have that issue as an "item
to solve" on the drawing board now, but we haven't gotten to it yet. If you
want, we can swap info on how to solve it as we discover. The downside is
that I expect it to be a couple of weeks before that particular item ends up
on anyone's plate over here.




Dan V. said:
Similar to my reply, Is there a faster / better method: With one key
difference; What about if I only lookup in the first column to find the
value in the 2nd column, as opposed to searching either column?

"I basically would like a 2 column array or whatever that will be
static,
as
in values won't change after I load them and I would like to fairly quickly
search for a value in -ONLY THE FIRST- column and either: 1. See if the
value exists or 2. get the value in the other column...."
array -
it
upon
how here
was
use
 
I'm not sure how to get around using get schema, but you can use similar
code with a hash table to avoid having to convert your data types (in trade,
you have to do casts, though):

myHashTable.Add(rdr.GetInt32(0), rdr.GetString(1)) should work fine.
However, when you go to retrieve the result, you have to cast the value back
to a string:

string value = (string)myHashTable[theIntKey];




Dan V. said:
The StringDictionary works great! Thanks.

I wish I could use code like this for Integers or strings in a DataReader.

MyStringDictionary.Add( rdr.GetString(0), rdr.GetString(1) )

It throws an exception if the first column is an Int32, so I have to know
the exact DataType and must resort to:

MyStringDictionary.Add( Convert.ToString(rdr.GetInt32(0)),
rdr.GetString(1) );

Aside: Now I could save a lot of code if I could find the DataType of a
column in the OleDbDataReader.
Using GetSchema is a bit slow.


J.Marsch said:
If you are only looking up the first column, so you have like a key-value
relationship, I would lean pretty heavily towards either the HashTable, the
StringDictionary, or the NameObjectCollectionBase. That's really what
they're made for, and the access is really fast.

The differences between them: A straight Hashtable accepts type object as
the key and returns type object as the value (so you can pass a string or
whatever as the key, and you will have to cast the value back:

myHashTable.Add("TheKey", aValue);
myType value = (myType)myHashTable["TheKey"];

A StringDictionary expects to be a list of string pairs, so that the add
method expects only strings:
myStringDictionary.Add("TheKey", "TheValue")
string value = myStringDictionar["TheKey"]

A NameObjectCollectionBase is an abstract class that you override to
customize it to your collection needs:
myNameObjectCollection.Add("TheKey", aValue);
myType value = myNameObjectCollection["TheKey"];

The benefit of the hashtable/dictionary is extremely speedy lookup.

Working where you want to access multiple columns is a little more
interesting. Right now, the only thing I have is brute force (2 hashtables,
swapping the key/value roles). We are actually have that issue as an "item
to solve" on the drawing board now, but we haven't gotten to it yet. If you
want, we can swap info on how to solve it as we discover. The downside is
that I expect it to be a couple of weeks before that particular item
ends
up
on anyone's plate over here.




static, array -
it worth,
the
(based
However,
a virtually
no
When
 
Back
Top