如何使用Linq从两个字典列表中获取唯一值
本文关键字:列表 字典 获取 唯一 两个 Linq 何使用 | 更新日期: 2023-09-27 18:15:11
这是我的代码
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}]
最后我想输出像
data3[0]=[0][{id,103}]
[1][{name,three}]
[2][{marks,89}]
[3][{state,usa}]
在上面的代码中我有两个列表的字典,我想比较两个列表得到唯一的id值。上述两个列表的键名是不同的,除了基于第一个列表id和第二个列表roleid的两个列表的值。
假设您想与列表相交:
使用相交法。首先实现两个字典之间的比较器:
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;
}
}
然后像这样使用:
var result = data1.Union(data2).Except(data1.Intersect(data2, new DictComparer()), new DictComparer());
编辑:注意到他想要的正好相反。修改了相应的功能。编辑2:我缺少字典的GetHashCode的正确实现。这个实现似乎可以工作:link
如果你想使用字典的Id来比较它们,你必须实现一个自定义比较器
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();
}
}
那么你可以使用
var dictCmp = new DictComparerById();
var data3 = data1
.Union(data2, dictCmp)
.Except(data1.Intersect(data2, dictCmp), dictCmp);