[英]C# Linq data structure, for eventual data binding. Best way to do?
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: 例如:
Part 1
Width 200
Depth 400
Voltage 240V
I'm storing the parts and their attributes in a dictionary like this: 我将部件及其属性存储在字典中,如下所示:
Dictionary<string, Dictionary<string, string>> parts;
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). 所以我可以看到一个部件是否存在parts.ContainsKey(部分),如果存在,我可以看看是否存在部件[part] .ContainsKey(属性)的属性。 So far, so banal. 到目前为止,如此平庸。
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). 我可以访问整个集合中所有属性的列表,如List(实际生产系统中有59个可能的属性)。
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). 每个部分的一个字符串列表(每个部分一个“行”)。
I'm pretty sure there's a simple one liner Linq statement for this. 我很确定这是一个简单的单线Linq声明。 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? 任何人都可以帮我解决这个问题吗?
I provide a full repro below (add a new C# console project), with some example data. 我在下面提供了一个完整的repro(添加一个新的C#控制台项目),以及一些示例数据。
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// The set of parts.
Dictionary<string, Dictionary<string, string>> hashPartToAttributes = new Dictionary<string,Dictionary<string,string>>();
hashPartToAttributes.Add("Part 1", new Dictionary<string,string>());
hashPartToAttributes.Add("Part 2", new Dictionary<string,string>());
hashPartToAttributes.Add("Part 3", new Dictionary<string,string>());
hashPartToAttributes.Add("Part 4", new Dictionary<string,string>());
// 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<string> attributeKeys = new List<string>() {
"Width", "Height", "Depth", "Voltage", "Bandwidth", "Frequency"
};
// Now construct a row for each part.
List<List<string>> rows = new List<List<string>>();
foreach (string part in hashPartToAttributes.Keys)
{
List<string> row = new List<string>() { part };
foreach (string key in attributeKeys)
{
Dictionary<string, string> attributes = hashPartToAttributes[part];
if (attributes != null && 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<string> row in rows)
{
foreach (string item in row)
{
if (item != null)
{
Console.Write("{0, -10}", item);
}
else
{
Console.Write("{0, -10}", "-");
}
}
Console.WriteLine();
}
}
}
}
A trivial LINQ statement doesn't exist, but you can use the following: 一个简单的LINQ语句不存在,但您可以使用以下内容:
hashPartToAttributes.Select(
p => new [] { p.Key }.Concat(
attributeKeys.GroupJoin(p.Value, ak => ak, a => a.Key,
(ak, a) => a.Select(x => x.Value).SingleOrDefault())
.DefaultIfEmpty())
.ToArray()
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.