tags:

views:

457

answers:

7

I want to keep some totals for different accounts. In C++ I'd use STL like this:

map<string,double> accounts;

// Add some amounts to some accounts.
accounts["Fred"] += 4.56;
accounts["George"] += 1.00;
accounts["Fred"] += 1.00;

cout << "Fred owes me $" << accounts['Fred'] << endl;

Now, how would I do the same thing in C# ?

+11  A: 
Dictionary<string, double> accounts;
Daniel A. White
+2  A: 

You want the Dictionary class.

Daniel Pryden
+6  A: 

Roughly:-

var accounts = new Dictionary<string, double>();

// Initialise to zero...

accounts["Fred"] = 0;
accounts["George"] = 0;
accounts["Fred"] = 0;

// Add cash.
accounts["Fred"] += 4.56;
accounts["George"] += 1.00;
accounts["Fred"] += 1.00;

Console.WriteLine("Fred owes me ${0}", accounts["Fred"]);
kronoz
This is very close to what I need, the only drawback is I do not know what the names of the accounts will be ahead of time.
Adam Pierce
You don't need to know them ahead of time. The examples use constant strings for brevity, but you can use string objects.
XXXXX
Perhaps I should clarify that comment by saying "I do not know the names, or how many names I will have". In this answer, if I added accounts["Ron"] += 2.50;, it would throw an exception. In reality, I'll be throwing an XML file at it with lots of names and numbers.
Adam Pierce
Actually no, if you use the index and attempt to set a non-existent key, it will actually create the object for you with the specified key. An exception will only be thrown on the get operation.Look here on remarks: http://msdn.microsoft.com/en-us/library/9tee9ht2.aspx
Alastair Pitts
Erebus is correct: You can arbitrarily add things to a Dictionary without knowing at compile time what or how many elements will be in the dictionary.
XXXXX
A: 

Dictionary is the most common, but you can use other types of collections, e.g. System.Collections.Generic.SynchronizedKeyedCollection, System.Collections.Hashtable, or any KeyValuePair collection

Jim Schubert
+3  A: 

This code is all you need:

   static void Main(string[] args) {
        String xml = @"
            <transactions>
                <transaction name=""Fred"" amount=""5,20"" />
                <transaction name=""John"" amount=""10,00"" />
                <transaction name=""Fred"" amount=""3,00"" />
            </transactions>";

        XDocument xmlDocument = XDocument.Parse(xml);

        var query = from x in xmlDocument.Descendants("transaction")
                    group x by x.Attribute("name").Value into g
                    select new { Name = g.Key, Amount = g.Sum(t => Decimal.Parse(t.Attribute("amount").Value)) };

        foreach (var item in query) {
            Console.WriteLine("Name: {0}; Amount: {1:C};", item.Name, item.Amount);
        }
    }

And the content is:

Name: Fred; Amount: R$ 8,20;
Name: John; Amount: R$ 10,00;

That is the way of doing this in C# - in a declarative way!

I hope this helps,

Ricardo Lacerda Castelo Branco

Ricardo Lacerda Castelo Branco
Well, I've already done it with Dictionary now but the XML is real simple, just a list of tags like this: <transaction name="Fred" amount="5.20" />
Adam Pierce
+1  A: 

Although System.Collections.Generic.Dictionary matches the tag "hashmap" and will work well in your example, it is not an exact equivalent of C++'s std::map - std::map is an ordered collection.

If ordering is important you should use SortedDictionary.

Paul Baker
+1  A: 

While we are talking about STL, maps and dictionary, I'd recommend taking a look at the C5 library. It offers several types of dictionaries and maps that I've frequently found useful (along with many other interesting and useful data structures).

If you are a C++ programmer moving to C# as I did, you'll find this library a great resource (and a data structure for this dictionary).

-Paul

Paul