Newbie : How to store 50 data elements effciently

I

indtaz

I need to store 50 "string" values and then retrieve information
selectively. I am looking for an efficient way to store/retrieve this
information.

Here is a bit more specific information:

I have to store the names of cities and states.
Essentially, the data I have is structured as follows:

a ) I have 5 State(s) names. eg..Ohio, Iowa, Michigan,
Illinois,Kentucky
b) For each State, I have a list of cities that I need to store...
eg Illinois -> Chicago, etc..
Michigan -> Dearborn etc...

Is creating a 5x10 array and storing the information, a good way to go
about doing this...or is there a better/more efficient way to do
this...

I have looked at the concept of 'structs'..but I dont seemed to have
fully understood how to go about using them...

Any pointers/suggestions ...would be much appreciated...

Thnkx...

RS
 
B

Bill Butler

I need to store 50 "string" values and then retrieve information
selectively. I am looking for an efficient way to store/retrieve this
information.

Here is a bit more specific information:

I have to store the names of cities and states.
Essentially, the data I have is structured as follows:

a ) I have 5 State(s) names. eg..Ohio, Iowa, Michigan,
Illinois,Kentucky
b) For each State, I have a list of cities that I need to store...
eg Illinois -> Chicago, etc..
Michigan -> Dearborn etc...
<snip>

I would use a Dictionary of Lists
like this

Dictionary<string, List<string>> states = new Dictionary<string,
List<string>>();
List<string> cities = new List<string>();
cities.Add("New York");
cities.Add("Albany");
states["New York"] = cities;
...


I
 
P

Peter Duniho

[...]
a ) I have 5 State(s) names. eg..Ohio, Iowa, Michigan,
Illinois,Kentucky
b) For each State, I have a list of cities that I need to store...
eg Illinois -> Chicago, etc..
Michigan -> Dearborn etc...

Is creating a 5x10 array and storing the information, a good way to go
about doing this...or is there a better/more efficient way to do
this...

I have looked at the concept of 'structs'..but I dont seemed to have
fully understood how to go about using them...

All due respect, you need to be reasonably familiar with both structs and
classes before you try to do anything of import in C#. (Likewise any
similar data structures that might exist in any language you might be
using). They are fundamental to the use of the language, and if you don't
understand how a struct or a class works, you're not ready to try to write
a program that does something useful (obviously there are lots of more
basic programs that you might write, and which in fact would be a
worthwhile exercise as you learn about the language).

Now, all that said, it seems to me that a multi-dimensional array isn't
really what you want here. It would work (though it's not clear from your
question that only being able to store 10 city names is acceptable), but
it's somewhat crude compared to the alternatives.

The most basic solution would be to have five named arrays:

string[] rgstrOhio = { "Cincinatti", "Akron", "Cleveland" };
string[] rgstrIowa = { "Iowa City", "Des Moines", "Dubuque" };
// etc.

(of course, you are not limited to three cities for each state...you can
put as many into each array as you like).

Unless you already have a natural mapping from a state name to an index,I
think this would be at least as good as a multi-dimensional array, if not
better. I suppose that if you did already have a direct mapping from
state name to index, you could do something like this:

string[][] rgrgstrCities = { { "Cincinatti", "Akron", "Cleveland"},
{ "Iowa City", "Des Moines", "Dubuque"},
// etc. };

But then you'd have to get the city arrays by indexing the rgrgstrCities
array with an integer derived from the state name. IMHO, it's better if
you can just use the state name directly, at least assuming that you
actually care about the state name at all.

If you want to be able to look up a given list of cities by state name and
don't want a hard-coded switch() statement or require an explicit mapping
from a state name to an integer as above or something like that, you could
use a Dictionary<>:

Dictionary<string, string[]> dictCitiesOfStates = new
Dictionary<string, string>();

dictCitiesOfStates.Add("Ohio", new string[] { "Cincinatti", "Akron",
"Cleveland" });
dictCitiesOfStates.Add("Iowa", new string[] { "Iowa City", "Des
Moines", "Dubuque" });
// etc.

There are other collection types as well. For example, instead of a
string[], you could use a List<string>, which would allow you to add or
remove states dynamically much more simply than would be possible with a
string[]. Or, you could use a Dictionary<> also for that collection,
which would allow you to associate some specific data with each city.

Frankly, how best to store this data has a lot more to do with how you're
going to use the data than it does with what the data actually is. So
far, all you've really told us is the latter, so vague answers like those
above are about as good as we can do, without more information.

Pete
 
M

Marc Gravell

Further to the other 2 replies mentioning
Dictionary<string,List<string>> and Dictionary<string,string[]>...

..NET 3.5 has a new ILookup<TKey,TValue> interface that maps a single
key to multiple values. Annoyingly, the provided implementation
(Lookup<TKey,TValue>) is readonly so isn't much use except as a result
from ToLookup - but I have an alternative implementation
(EditableLookup<TKey,TValue>) which might be of use to people - for
instance:

var lookup = new EditableLookup<string,string>();
lookup.Add("Foo","Somewhere");
lookup.Add("Foo","Somewhere else");
lookup.AddRange("Bar",new[] {"Whatever", "You", "Want"});
lookup.Add("Bar","etc");
(with standard access to the unique keys, and the items per key, etc)

Let me know...

Marc
 
J

Jon Skeet [C# MVP]

Further to the other 2 replies mentioning
Dictionary<string,List<string>> and Dictionary<string,string[]>...

.NET 3.5 has a new ILookup<TKey,TValue> interface that maps a single
key to multiple values. Annoyingly, the provided implementation
(Lookup<TKey,TValue>) is readonly so isn't much use except as a result
from ToLookup - but I have an alternative implementation
(EditableLookup<TKey,TValue>) which might be of use to people - for
instance:

<snip>

While we're talking about custom code, there's another alternative
approach I've been considering for a little while.

I would like a form of Dictionary<TKey,TValue> which took a delegate
Func<TValue>. When a lookup was performed with the indexer (or
possibly with a new method to make the rest of the behaviour
consistent with the existing class), if the key wasn't present it
would be added, with the result of calling the delegate. The new value
would then be returned. We could then do:

var dict = new JonDictionary<string,List<string>>( () => new
List<string>() );
dict.Lookup("Foo").Add("bar");
dict.Lookup("Foo").Add("baz");
dict.Lookup("Numbers").Add("1");
etc

Any thoughts, anyone?

Jon
 
M

Marc Gravell

Any thoughts, anyone?

How about this then? No need for a custom dictionary ;-p

static void Main() {
var dict = new Dictionary<string, List<string>>();
dict.AutoAdd("Foo", "Bar");
dict.AutoAdd("Foo", "Baz");
dict.AutoAdd("Number", "1");
dict.AutoAdd("Foo", "Bop");
}

public static class DictionaryExt {
public static void AutoAdd<TKey, TList, TValue>(
this IDictionary<TKey, TList> dict, TKey key, TValue value
) where TList : IList<TValue>, new() {

TList list;
if (!dict.TryGetValue(key, out list)) {
list = new TList();
dict.Add(key, list);
}
list.Add(value);
}
}
 
M

Marc Gravell

Actually you can probably rename to Add; I was just cautious of a
conflict (where IDictionary<TKey,TValue> would win), but there is no
way (that I can see) that TKey and TValue can be the same (while also
satisfying the condition).

Then you just have:
var dict = new Dictionary<string, List<string>>();
dict.Add("Foo", "Bar");
dict.Add("Foo", "Baz");
dict.Add("Number", "1");
dict.Add("Foo", "Bop");

Job done ;-p

Marc
 
J

Jon Skeet [C# MVP]

How about this then? No need for a custom dictionary ;-p

Oh, bravo. It only works for the list case, but it's still neat.
Actually, I wonder if you could change it to:

public static class DictionaryExt
{
public static TValue LookupOrAdd<TKey, TValue>
(this IDictionary<TKey, TValue> dict, TKey key)
where TValue : new()
{
TValue ret;
if (!dict.TryGetValue(key, out ret)) {
ret = new TValue();
dict.Add(key, ret);
}
return ret;
}
}

That would be more general, allowing lists, dictionaries, value types
etc. I haven't tried it at all though.

One advantage of putting it in the indexer in a "proper" custom class
would be to allow for things like:

var dict = new JonDictionary<string,int>();
dict["Foo"]++; // No need to check for 0 to start with

but even with the above extension you could do:

dict["Foo"] = dict.LookupOrAdd("Foo")+1;

Duplication of the key, unfortunately :(

Jon
 
M

Marc Gravell

That would be more general, allowing lists, dictionaries, value
types
etc. I haven't tried it at all though.

Good point; sorry, I still had my ILookup goggles on (hence focusing
on Add)... but there's room for more than one extension method ;-p

Either way, it isn't often you can find an (actually useful) example
that has such a blend of extension methods, type inference, generics,
and multiple interdependent type constraints... maybe we could squeeze
a delegate in their (ctor, perhaps) just to get the full range of
language features in the signature ;-p

Marc
 

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