C# version of std::map

T

Torben Laursen

Hi

Can anyone tell me if there is a class in C# similar to the class std::map
in C++?

I need a way to map enum to double and was hoping to avoid using any "if"
code
Thanks Torben
 
J

Joanna Carter [TeamB]

"Torben Laursen" <[email protected]> a écrit dans le message de OdKV%[email protected]...

| Can anyone tell me if there is a class in C# similar to the class std::map
| in C++?
|
| I need a way to map enum to double and was hoping to avoid using any "if"
| code

System.Collections.Hashtable in .NET 1.1

System.Collections.Generic.Dictionary<k,v> in .NET 2.0

Joanna
 
T

Torben Laursen

Thanks
I looked at that but I need a way to get a 2D map.
This is my C++ code:
enum Units {Pa=0, Bar, Atm, kPa, Psi, MPa};
std::map<Units, std::map<Units, double> > P2P_;

Then I can use P2P_ as: P2P_[Pa][Bar] where it returns a double

It there a way to do this in C#?

Thanks Torben
 
J

Joanna Carter [TeamB]

"Torben Laursen" <[email protected]> a écrit dans le message de (e-mail address removed)...

| I looked at that but I need a way to get a 2D map.
| This is my C++ code:
| enum Units {Pa=0, Bar, Atm, kPa, Psi, MPa};
| std::map<Units, std::map<Units, double> > P2P_;
|
| Then I can use P2P_ as: P2P_[Pa][Bar] where it returns a double
|
| It there a way to do this in C#?

How about Dictionary<Units, Dictionary<Units, double>> ??

public enum Units
{
Pa = 0, Bar, Atm, kPa, Psi, MPa
}

class Program
{
static void Main(string[] args)
{
Dictionary<Units, Dictionary<Units, double>> p2p = new
Dictionary<Units,Dictionary<Units,double>>();

Dictionary<Units, double> newEntry = new Dictionary<Units,double>();

newEntry.Add(Units.Atm, 12.34);

p2p.Add(Units.Pa, newEntry);

double result = p2p[Units.Pa][Units.Atm];

System.Console.WriteLine(result);

System.Console.ReadLine();
}
}

Joanna
 
A

adebaene

Joanna said:
"Torben Laursen" <[email protected]> a écrit dans le message de OdKV%[email protected]...

| Can anyone tell me if there is a class in C# similar to the class std::map
| in C++?
|
| I need a way to map enum to double and was hoping to avoid using any "if"
| code

System.Collections.Hashtable in .NET 1.1

System.Collections.Generic.Dictionary<k,v> in .NET 2.0

Although the interface is similar, you need to be aware that the
implementation is quite different, and so will be the performances :
std::map is sorted according to the key whereas HashTable and
Dictionnary are hash-based collections. The complexity of the various
operations on the container are therefore quite different, as are the
operations that are authorized on the container (for example, .NET
forbids to modify in any way the container's content during an
enumeration on it).

Arnaud
MVP - VC
 
L

Lucian Wischik

Although the interface is similar, you need to be aware that the
implementation is quite different, and so will be the performances :
std::map is sorted according to the key whereas HashTable and
Dictionnary are hash-based collections.

SortedList<Tkey,Tvalue> and SortedDictionary<Tkey,Tvalue> are the two
key-sorted dictionaries available in c#. I never remember what the
difference is.
 
J

Jon Skeet [C# MVP]

Lucian Wischik said:
SortedList<Tkey,Tvalue> and SortedDictionary<Tkey,Tvalue> are the two
key-sorted dictionaries available in c#. I never remember what the
difference is.

From the docs (I didn't know either):

<quote>
Where the two classes differ is in memory use and speed of insertion
and removal:

SortedList uses less memory than SortedDictionary.

SortedDictionary has faster insertion and removal operations for
unsorted data, O(log n) as opposed to O(n) for SortedList.

If the list is populated all at once from sorted data, SortedList is
faster than SortedDictionary.

Another difference between the SortedDictionary and SortedList classes
is that SortedList supports efficient indexed retrieval of keys and
values through the collections returned by the Keys and Values
properties. It is not necessary to regenerate the lists when the
properties are accessed, because the lists are just wrappers for the
internal arrays of keys and values.
</quote>
 
N

Nick Hounsome

Dictionary<Units, Dictionary<Units, double>> is not really satisfactory
because, in general, you need to explicitly create Dictionary<Units,double>
and (worse), if you want to add to P2P_[Units.Pa] you must first check
whether or not it exists because it is a reference type.

There are three solutions - the first gives you the syntax that you want but
is quite tedious to code:

1) Create a struct StructDictionary<K,V> implementing IDictionary<K,V> that
lazily creates a Dictionary<K,V> and delegates everything to it. Then use
Dictionary<Units,StructDictionary<Units,double>>.

The second is shorter and more efficient but does have slightly different
capabilities and syntax.

2) Create a struct Pair<K1,K2> with Equals and GetHashCode overrides and use
Dictionary<Pair<Units,Units>,double>. This seems to give what you are
actually trying to do which is a unit conversion table.

In either case you should probably be hiding the whole thing in a class with
"double Convert(Units fromUnits,Units toUnits,double value)"

Note also that to be able to do all conversions you need a delegate rather
than a double since otherwise you cannot convert from centigrade to either
Fahrenheit or Kelvin. Alternatively conversions of the form y = mx+c can be
handled by a two part structure holding m and c. The data approach has the
advantage that you only need to populate the conversion one way - if the
conversion method can't find Fahrenheit to centigrade it can look up
centigrade to fahrenheit and invert it.

For maximum flexibility you should use strings rather than enums so that you
can load conversions from a database or file. (use static strings for
hardwired stuff)
 

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