title: C# Linq data structure, for eventual data binding. Best way to do?
body: <p>I have a set of "parts".  Each part has a name and set of attributes.  An attribute is a set of string keys and values.  For example:</p>
  
  <pre><code>Part 1
      Width   200
      Depth   400
      Voltage 240V
  </code></pre>
  
  <p>I'm storing the parts and their attributes in a dictionary like this:</p>
  
  <pre><code>Dictionary&lt;string, Dictionary&lt;string, string&gt;&gt; parts;
  </code></pre>
  
  <p>So I can see if a part exists with parts.ContainsKey(part) and if it does, I can then
  see if an attribute exists with parts[part].ContainsKey(attribute).  So far, so banal.</p>
  
  <p>Now what I want to do is either data bind this structure, or otherwise generate a set 
  of rows, where each column is an attribute.  Not all parts have all attributes, so there will be "nulls" in places. I have access to a list of all attributes found in the entire set, as List (there are 59 possible attributes in the actual production system).</p>
  
  <p>My code for generating a set of rows, assuming the first column is the part name, is the
  rather clunky code below.  It results in a List of Lists of string.  One List of String
  for each part (one "row" for each part).</p>
  
  <p>I'm pretty sure there's a simple one liner Linq statement for this.  I'm hoping I can use
  it to data-bind to a list or data grid to display it at some point.  Can anyone help me out with it?</p>
  
  <p>I provide a full repro below (add a new C# console project), with some example data.</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  
  namespace ConsoleApplication1
  {
      class Program
      {
          static void Main(string[] args)
          {              
              // The set of parts.
  
              Dictionary&lt;string, Dictionary&lt;string, string&gt;&gt; hashPartToAttributes = new Dictionary&lt;string,Dictionary&lt;string,string&gt;&gt;();
  
              hashPartToAttributes.Add("Part 1", new Dictionary&lt;string,string&gt;());
              hashPartToAttributes.Add("Part 2", new Dictionary&lt;string,string&gt;());
              hashPartToAttributes.Add("Part 3", new Dictionary&lt;string,string&gt;());
              hashPartToAttributes.Add("Part 4", new Dictionary&lt;string,string&gt;());
  
              // Add in all attributes for all of the parts.
  
              {
                  hashPartToAttributes["Part 1"].Add("Width", "200");
                  hashPartToAttributes["Part 1"].Add("Height", "400");
                  hashPartToAttributes["Part 1"].Add("Depth", "600");
  
                  hashPartToAttributes["Part 2"].Add("Width", "300");
                  hashPartToAttributes["Part 2"].Add("Height", "700");
                  hashPartToAttributes["Part 2"].Add("Depth", "100");
                  hashPartToAttributes["Part 2"].Add("Voltage", "240V");
  
                  hashPartToAttributes["Part 3"].Add("Voltage", "110V");
                  hashPartToAttributes["Part 3"].Add("Bandwidth", "25");
                  hashPartToAttributes["Part 3"].Add("Frequency", "5");
                  hashPartToAttributes["Part 3"].Add("Height", "900");
  
                  hashPartToAttributes["Part 4"].Add("Width", "150");
                  hashPartToAttributes["Part 4"].Add("Height", "740");
                  hashPartToAttributes["Part 4"].Add("Depth", "920");
                  hashPartToAttributes["Part 4"].Add("Voltage", "240V");
                  hashPartToAttributes["Part 4"].Add("Bandwidth", "40");
                  hashPartToAttributes["Part 4"].Add("Frequency", "5");
              }
  
              // The complete set of all attributes (column headings)
  
              List&lt;string&gt; attributeKeys = new List&lt;string&gt;() {
                  "Width", "Height", "Depth", "Voltage", "Bandwidth", "Frequency"
              };
  
              // Now construct a row for each part.
  
              List&lt;List&lt;string&gt;&gt; rows = new List&lt;List&lt;string&gt;&gt;();
  
              foreach (string part in hashPartToAttributes.Keys)
              {
                  List&lt;string&gt; row = new List&lt;string&gt;() { part };
  
                  foreach (string key in attributeKeys)
                  {
                      Dictionary&lt;string, string&gt; attributes = hashPartToAttributes[part];
  
                      if (attributes != null &amp;&amp; attributes.ContainsKey(key))
                      {
                          row.Add(attributes[key]);
                      }
                      else
                      {
                          row.Add(null);
                      }
                  }
  
                  rows.Add(row);
              }           
  
              // Print out headings.
  
              Console.Write("{0, -10}", "Part");
  
              foreach (string heading in attributeKeys)
              {
                  Console.Write("{0, -10}", heading);
              }
  
              Console.WriteLine();
              Console.WriteLine();
  
              // Print out the rows
  
              foreach (List&lt;string&gt; row in rows)
              {
                  foreach (string item in row)
                  {
                      if (item != null)
                      {
                          Console.Write("{0, -10}", item);
                      }
                      else
                      {
                          Console.Write("{0, -10}", "-");
                      }
                  }
  
                  Console.WriteLine();
              }
          }
      }
  }
  </code></pre>