4

This is my code

public class Model
{
    public Model();

    public Dictionary<string, string> Data { get; set; }

}

list<dictionary<string,string>>  data1;
list<dictionary<string,string>>  data2;

data1=await get<model>();
data2=await get<model>();

data1[0]=[0][{id,101}]
         [1][{name,one}]
         [2][{marks,56}]
         [3][{state,ap}]     

data1[1]=[0][{id,102}]
         [1][{name,two}]
         [2][{marks,65}]
         [3][{state,up}]     

data1[2]=[0][{id,103}]
         [1][{name,three}]
         [2][{marks,89}]
         [3][{state,usa}]     



data2[0]=[0][{roleid,101}]
         [1][{stdname,one}]
data2[1]=[0][{roleid,102}]
         [1][{stdname,two}]

Finally i want Output Like

data3[0]=[0][{id,103}]
         [1][{name,three}]
         [2][{marks,89}]
         [3][{state,usa}]     

in the above code i have two list of dictionaries, i want to get unqiue id values compare two lists.the above two lists key names are different get except values from two lists based on first list id and second list roleid.

  • I'm not clear are you looking for dictionary entries that exist in only one of the dictionaries in the two lists, or just entries that are in the dictionaries of one list, but not the other. Also does the value being the same come into play? If so you could end up with duplicate keys with different values. – juharr Sep 30 '15 at 11:53

2 Answers2

2

Assuming you would like to intersect to lists:

Use the intersect method. First implement a comparer between two dictionaries:

public class DictComparer : IEqualityComparer<Dictionary<string, string>>
{
    public bool Equals(Dictionary<string, string> x, Dictionary<string, string> y)
    {
        return (x == y) || (x.Count == y.Count && !x.Except(y).Any());
    }

    public int GetHashCode(Dictionary<string, string> x)
    {
        var ret = 123;
        foreach (var keyValue in x)
        {
            ret = ret + (keyValue.GetHashCode() * 31);
        }
        return ret;
    }
}

Then use it like this:

var result = data1.Union(data2).Except(data1.Intersect(data2, new DictComparer()), new DictComparer());

Edit: noticed he wanted the exact opposite. Changed the function accordingly. Edit2: I was missing a proper implementation of GetHashCode for dictionaries. This implementation seems to work: link

Maor Veitsman
  • 1,544
  • 9
  • 21
2

If you want to compare the dictionaries using their Id you must implement a custom comparer

public class DictComparerById : IEqualityComparer<Dictionary<string, string>>
{
    public bool Equals(Dictionary<string, string> x, Dictionary<string, string> y)
    {
        // Two dictionary are equal if the have the same "id"
        string idX;
        if(!x.TryGetValue("id", out idX))
            x.TryGetValue("roleid", out idX);

        string idY;
        if(!y.TryGetValue("id", out idY))
            y.TryGetValue("roleid", out idY);

        return (idX == idY);
    }

    public int GetHashCode(Dictionary<string, string> x)
    {
        string id;
        if(!x.TryGetValue("id", out id))
            x.TryGetValue("roleid", out id);
        return id.GetHashCode();
    }
}

Then you can use

var dictCmp = new DictComparerById();
var data3 = data1
    .Union(data2, dictCmp)
    .Except(data1.Intersect(data2, dictCmp), dictCmp);
deramko
  • 2,807
  • 1
  • 18
  • 27