The code below will combine 3 separate tables into one based on the order of importance. I am looking to improve this - perhaps by using query syntax to avoid the intermediate stage. Are there different (better?) ways of achieving the same result?
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 output:
Key | Value
------------
f1 | f1-upsert
f2 | f2-server
f3 | f3-fields
f4 | f4-fields
f5 | f5-server
f6 | f6-upsert
This may or may not be what you're looking for, but personally I find that LINQ pretty difficult to read.
Here is a method which will duplicate your logic on as many collections as you'd like:
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();
}
To call it: CombineWithPriority(upsert, fields, server)
. You can add more levels as well, all with descending priority.
The biggest difference (besides readability, in my opinion) between this method and yours is that this method doesn't allocate temporary lists.
You can use a GroupBy
and select only the first value:
upsert.Concat(fields).Concat(server)
.GroupBy(x => x.Key, (k, g) => g.First())
.OrderBy(x => x.Key)
.Dump();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With