简体   繁体   中英

Is there one liner LINQ construct for creating dictionary by merging two lists and removing duplicates

I have two classes, and two collections of each:

public class ClassA {
    String key;
    String value;
    // Some other fields specific to ClassA
}

public class ClassB {
    String key;
    String value;
    // Some other fields specific to ClassB
}

List<ClassA> listA;
List<ClassB> listB;

I want to build Dictionary<String, String> from key and value from listA and listB where value would be from listB if both lists contain object with same key but different value s.

Now, I have a solution - create dictionaryA from listA , create dictionaryB from listB , merge those dictionaries by properly handling duplicates. There are several SO posts explaining how to do just that.

My question is bit more academic - Is there one liner LINQ construct that can do what I want to do?

Here is one way:

 var merged =
     listA.Select(b => new { key = b.key, val = b.value })
     .Union(listB.Select(b => new { key = b.key, val = b.value }))
     .ToDictionary(m => m.key, n => n.val);;

Please note that this will not handle objects that have the same key but different value.

To deal with duplicates you'd need:

 var d = listA.Select(b => new { key = b.key, val = b.value })
              .Union(listB.Select(b => new { key = b.key, val = b.value }))
              .GroupBy(x => x.key)
              .Select(x => x.First())
              .ToDictionary(m => m.key, n => n.val);

Please note this keeps only the first record with a given key and records with the same key, but different value are lost.


Test code

public static void Main(string[] args)
{
    List<ClassA> listA = new List<ClassA>() { 
        new ClassA() { key = "A", value = "1" }, 
        new ClassA() { key = "B", value = "2" }};
    List<ClassB> listB = new List<ClassB>() { 
        new ClassB() { key = "B", value = "2" }, 
        new ClassB() { key = "C", value = "3" }, 
        new ClassB() { key = "A", value = "4" }};

    var d = (...)

    foreach( var kvp in d ) {
        Console.WriteLine($"{kvp.Key}: {kvp.Value} ");
    }
}

Result

A: 1
B: 2
C: 3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM