我有一个xml文件,如:
<root>
<RowDetails RowName="A" ColumnSize="1">
<ColumnDetails ColumnName="A1" />
</RowDetails>
<RowDetails RowName="B" ColumnSize="2">
<ColumnDetails ColumnName="B1" />
<ColumnDetails ColumnName="B2" />
</RowDetails>
<RowDetails RowName="C" ColumnSize="3">
<ColumnDetails ColumnName="C1" />
<ColumnDetails ColumnName="C2" />
<ColumnDetails ColumnName="C3" />
</RowDetails>
</root>
和像这样的词典:
Dictionary<String, List<String>>MyDict = new Dictioanary<String, List<String>>();
我正在阅读MyDict
的XML文件,如:
XDocument XDoc = XDocument.Load(Application.StartupPath + @"\foo.xml");
MyDict = XDoc.Descendants("RowDetails").ToDictionary(X => X.Attribute("RowName").Value,
X => X.Descendants("ColumnDetails")
.Select(Y => Y.Attribute("ColumnName").Value).ToList());
现在字典将包含:
"A" { "A1" }
"B" { "B1", "B2" }
"C" { "C1", "C2", "C3" }
但我的问题是我需要所有列表具有相同的计数。应为空条目添加空字符串,因此预期结果为:
"A" { "A1", "", "" }
"B" { "B1", "B2", "" }
"C" { "C1", "C2", "C3" }
如何修改LINQ查询?
请使用LINQ帮助我这样做。
提前致谢。
答案 0 :(得分:5)
假设您希望在创建MyDict
之后将其作为后处理步骤完成,那么基本想法将是:
// The required size is the count of the biggest list
var sizeRequired = MyDict.Values.Max(l => l.Count);
// Pad each list as necessary
foreach (var list in MyDict.Values)
list.AddRange(Enumerable.Repeat(string.Empty, sizeRequired - list.Count));
这是一种返回具有所需特征的新词典而不改变原始集合的方法:
// The required size is the count of the biggest list
var sizeRequired = MyDict.Values.Max(l => l.Count);
// Each string key should map to a key in the new dictionary
// Each List<string> value should map to a new list, padded as necessary.
var paddedDict = MyDict.ToDictionary
(
kvp => kvp.Key,
kvp => kvp.Value
.Concat(Enumerable.Repeat(string.Empty, sizeRequired - kvp.Value.Count))
.ToList()
);
答案 1 :(得分:2)
您可以在IEnumerable<T>
上创建一个扩展方法,以填充到最小尺寸,内联:
public static class IEnumerableExtensions
{
public static IEnumerable<TSource> PadIfFewerThan<TSource>(
this IEnumerable<TSource> items,
int size, TSource padValue = default(TSource))
{
int count = 0;
foreach (var item in items)
{
++count;
yield return item;
}
foreach (var index in Enumerable.Range(count, size - count))
yield return padValue;
}
}
您生成的代码如下所示:
var dictionary = doc.Descendants("RowDetails")
.ToDictionary(
x => x.Attribute("RowName").Value,
x => x.Descendants("ColumnDetails")
.Select(y => y.Attribute("ColumnName").Value)
.PadIfFewerThan(3, "")
);
foreach (var entry in dictionary)
Console.WriteLine(@"""{0}"" {{""{1}""}}",
entry.Key,
string.Join(@""",""", entry.Value)
);
“A”{“A1”,“”,“”}
“B”{“B1”,“B2”,“”}
“C”{“C1”,“C2”,“C3”}
如果您必须拥有Dictionary<string, List<string>>
,而不是此处返回的Dictionary<string, IEnumerable<string>>
,只需将.ToList()
放回混音中:
var dictionary = doc.Descendants("RowDetails")
.ToDictionary(
x => x.Attribute("RowName").Value,
x => x.Descendants("ColumnDetails")
.Select(y => y.Attribute("ColumnName").Value)
.PadIfFewerThan(3)
.ToList()
);
答案 2 :(得分:-1)
我不确定“LINQ”中是否有某种方法......我可能也会在C#代码中做你想做的事。
但是,这个要求来自哪里?可能是代码应该在那里改变,它希望你的字典中的所有列表具有相同的大小?