【问题标题】:Intersecting two list of dictionary by values of only specific keys C#仅通过特定键 C# 的值将两个字典列表相交
【发布时间】:2015-10-27 21:01:54
【问题描述】:

我有两个不同长度的字典列表。两个字典中的键相同,值可能不同。

var A = List<Dictionary<string, object>>();
var B = List<Dictionary<string, object>>();

我想根据其中包含的字典对象中的 3 个键的值将 A 和 B 相交。

例如:

var dict = new Dictionary<string,object>{{"W",val1},{"X",val2},{"Y",val3},{"Z",val4}}

与上述类似的字典包含在列表 A 和 B 中,其中 val1、val2、val3、val4 的值各不相同。如果键 W、X、Y 的值相等,我想使 A 和 B 相交,但我不关心 Z 中的值是否相交。有没有办法优雅地实现这一点?

举例说明:

   A.add(new Dictionary<string,object>{{"W",123},{"X",456},{"Y",789},{"Z",103}});
   A.add(new Dictionary<string,object>{{"W",124},{"X",456},{"Y",789},{"Z",893}});
   A.add(new Dictionary<string,object>{{"W",123},{"X",456},{"Y",789},{"Z",134}});

   B.add(new Dictionary<string,object>{{"W",123},{"X",456},{"Y",789},{"Z",900}});
   B.add(new Dictionary<string,object>{{"W",124},{"X",456},{"Y",789},{"Z",893}});
   B.add(new Dictionary<string,object>{{"W",212},{"X",321},{"Y",789},{"Z",134}});

如果我执行 A.intersect(B),我希望得到以下列表,

{"W",123},{"X",456},{"Y",789},{"Z",103}
{"W",123},{"X",456},{"Y",789},{"Z",900}
{"W",124},{"X",456},{"Y",789},{"Z",893}

【问题讨论】:

  • 我不确定我是否理解这个问题。您能否举例说明在这种情况下所需的结果是什么?
  • 等等什么?你有两个字典列表?
  • 交叉点是什么意思?

标签: c# list dictionary


【解决方案1】:

这会给你一个 IEnumerable:

var c=A.Select(a=>new {W=a[W],X=a[X],Y=a[Y]})
  .Intersect(B.Select(a=>new {W=a[W],X=a[X],Y=a[Y]}));

或者,为自己创建一个自定义 IEqualityComparer,然后您可以这样做:

var c=A.Intersect(B,new MyComparer());

类似:

class MyComparer : IEqualityComparer<Dictionary<string,object>>
{
    public bool Equals(Dictionary<string,object> b1, Dictionary<string,object> b2)
    {
        if (b2 == null && b1 == null)
           return true;
        else if (b1 == null || b2 == null)
           return false;
        else if(b1["W"]==b2["W"] && b1["X"]==b2["X"] && b1["X"]==b2["X"])
            return true;
        else
            return false;
    }

    public int GetHashCode(Dictionary<string,object> bx)
    {
        int hCode = bx["W"] ^ bx["X"] ^ bx["Y"];
        return hCode.GetHashCode();
    }
}

【讨论】:

  • 可能需要稍作修改才能从 bx["W"] 等获取哈希码,因为它是一个对象。如果 W,X,Y 确实是字符串而不仅仅是占位符属性名称,则应在第一个示例中引用它们。
  • 工作正常,只是快速跟进。如果我想要相同的行为但喜欢使用 except 进行集合减法,这会起作用吗?
  • 是的。但是如果你同时做这两个,我真的建议使用 IEqualityComparer,或者创建一个继承自 Dictionary 的自定义类型,这样你就可以直接实现所需的接口。然后,您甚至根本不需要提供 IEqualityComparer 并让默认值起作用。
猜你喜欢
  • 2023-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
相关资源
最近更新 更多