以下代码将根据重要性顺序将3个单独的表组合成一个表。我希望改进这一点 - 也许通过使用查询语法来避免中间阶段。是否有不同的(更好的?)方法来实现相同的结果?
var upsert = new List<KeyValuePair<string, string>>() {
new KeyValuePair<string, string>("f1","f1-upsert"),
new KeyValuePair<string, string>("f6","f6-upsert")
};
var fields = new List<KeyValuePair<string, string>>() {
new KeyValuePair<string, string>("f3","f3-fields"),
new KeyValuePair<string, string>("f4","f4-fields"),
new KeyValuePair<string, string>("f6","f6-fields")
};
var server = new List<KeyValuePair<string, string>>() {
new KeyValuePair<string, string>("f1","f1-server"),
new KeyValuePair<string, string>("f2","f2-server"),
new KeyValuePair<string, string>("f5","f5-server")
};
// Order of importance: Upsert > Fields > Server !
var stage = upsert.Concat(fields.Where(f=> !upsert.Any(u=>u.Key==f.Key)));
var final = stage.Concat(server.Where(s=> !stage.Any(j=>j.Key==s.Key))).OrderBy(o=>o.Key);
final.Dump();
LINQPad输出:
Key | Value
------------
f1 | f1-upsert
f2 | f2-server
f3 | f3-fields
f4 | f4-fields
f5 | f5-server
f6 | f6-upsert
答案 0 :(得分:5)
这可能是也可能不是你想要的,但我个人觉得LINQ很难阅读。
这是一种方法,可以根据您的喜好在多个集合上复制您的逻辑:
public List<KeyValuePair<string, string>> CombineWithPriority(params List<KeyValuePair<string, string>>[] allLists)
{
var results = new Dictionary<string, string>();
foreach (var list in allLists)
{
foreach (var kvp in list)
{
if (!results.ContainsKey(kvp.Key))
{
results.Add(kvp.Key, kvp.Value);
}
}
}
return results
.OrderBy(kvp => kvp.Key)
.ToList();
}
致电:CombineWithPriority(upsert, fields, server)
。您也可以添加更多级别,所有级别都具有降序优先级。
此方法与您之间的最大区别(除了可读性之外),此方法不会分配临时列表。
答案 1 :(得分:4)
您可以使用GroupBy
并仅选择第一个值:
upsert.Concat(fields).Concat(server)
.GroupBy(x => x.Key, (k, g) => g.First())
.OrderBy(x => x.Key)
.Dump();