C # 等价于 C + + map < string,double >

我想为不同的帐户保留一些总数,在 C + + 中我会像这样使用 STL:

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;

现在,我要怎么在 C # 中做同样的事情呢?

184293 次浏览
Dictionary<string, double> accounts;

You want the Dictionary class.

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"]);

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

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

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.

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

The closest equivalent of C++ std::map<> (a tree internally) is C# OrderedDictionary<> (a tree internally), while C# OrderedDictionary<> is missing some very important methods from C++ std::map<>, namely: std::map::find, std::map::lower_bound, std::map::upper_bound, std::map::equal_range, and std::map iterators, which are basically the backbone for the previous 4 methods.

Why those 4 methods are important? Because it gives us the ability to locate the "whereabouts" of a given key, in addition to only being able to check if a key exists, or the SortedDictionary is guaranteed to be ordered.

What is "whereabouts" of a key in a std::map? The key doesn't necessarily have to exist in the collection, we want to know the location the key might be at, usually between two iterators pointing to two adjacent existing keys respectively in the collection, so we can operate on the range the key falls into in a O(logN) complexity. Without such 4 methods (with iterators), one has to do an O(N) iteration through the collection every time a range is queried against a key.