LINQ - query to combine 3 data sets - improvements

In the code below, 3 separate tables will be merged into one, based on the order of importance. I want to improve this - perhaps using query syntax to avoid an intermediate stage. Are there different (better?) Ways to achieve 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 
+4
source share
2 answers

You can use GroupByand select only the first value:

upsert.Concat(fields).Concat(server)
    .GroupBy(x => x.Key, (k, g) => g.First())
    .OrderBy(x => x.Key)
    .Dump();
+4
source

This may or may not be what you are looking for, but personally, I find LINQ quite difficult to read.

Here is a method that will duplicate your logic into as many collections as you would 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();
 }

: CombineWithPriority(upsert, fields, server). , .

( , ) , .

+5

Source: https://habr.com/ru/post/1693756/


All Articles