5

How can I create a Dictionary (or even better, a ConcurrentDictionary) using Linq?

For example, if I have the following XML

<students>
    <student name="fred" address="home" avg="70" />
    <student name="wilma" address="home, HM" avg="88" />
    .
    . (more <student> blocks)
    .
</students>

loaded into XDocument doc; and wanted to populate a ConcurrentDictionary<string, Info> (where the key is the name and Info is some class holding address and average. Populating Info is not my concern now), how would I do this?

Baruch
  • 20,590
  • 28
  • 126
  • 201

2 Answers2

9
XDocument xDoc = XDocument.Parse(xml);
var dict = xDoc.Descendants("student")
                .ToDictionary(x => x.Attribute("name").Value, 
                              x => new Info{ 
                                  Addr=x.Attribute("address").Value,
                                  Avg = x.Attribute("avg").Value });


var cDict = new ConcurrentDictionary<string, Info>(dict);
L.B
  • 114,136
  • 19
  • 178
  • 224
  • If `ConcurrentDictionary` is a must, it might be better to skip `.ToDictionary` and to load the sequence directly into an empty `ConcurrentDictionary` in a `foreach` loop. This will avoid creating a `Dictionary` (`dict`) that gets thrown away. – spender Nov 19 '12 at 11:19
3

Something like this will do:

var dict = xml.Descendants("student")
              .ToDictionary(r => (string)r.Attribute("name").Value, r => CreateInfo(r));

This produced just a usual Dictionary; you can construct a ConcurrentDictionary from the usual Dictionary.


Edit: changed Element to Attribute, thanks to @spender for noticing this. And "student" -> "students", thanks to @Jaroslaw.

Vlad
  • 35,022
  • 6
  • 77
  • 199
  • @Jaroslaw: no, actually -- is there a problem? If yes, you can help to improve the answer (or give your own one). – Vlad Nov 19 '12 at 10:56
  • just run this if you have time, so yo'll get an error. I don't see the point of pasting the exception in the comment. This is only the tip for you to take a look, for me it can stay as is. – jwaliszko Nov 19 '12 at 11:01
  • @Jaroslaw: I have got no compiler at hand. The point would be helping the readers to know the right answer, of course. – Vlad Nov 19 '12 at 11:02
  • Hmm. Why so cryptic, @Jaroslaw? In the mean time, I'd suggest reading an Attribute value rather than child Element value. – spender Nov 19 '12 at 11:03
  • @Vlad: ok, one more left, replace `xml.Descendants("students")` with `xml.Descendants("student")` at it gives more nodes not just the main one. – jwaliszko Nov 19 '12 at 11:12