按值比较 2 个词典的条目,然后 return 他们各自的键?

Comparing entries of 2 dictionaries by their values but then return their respective keys?

我有 2 个 Dictionary<int, (int, int)> 类型的字典,第一个 int 是它们的键,(int, int) 是它们的值。

使用 var intersections = dict1.Values.Intersect(dict2.Values); 我可以比较值和 return 两者之间重合的所有值的 IEnumerable,但是这并没有给我密钥。使用 var intersections = dict1.Keys.Intersect(dict2.Keys); 将 return 键出现在两个词典中,这是......每个键因为键只是从 1 开始并为每个条目递增 1,所以它没用。

我想通过值比较条目,然后访问它们的键。因此,例如,如果条目 (12, 36) 出现在 dict1 中的键 20 和 dict2 中的键 45 处,我希望有一种方法可以访问 20 和 45。

我完全不知所措。我能够比较值和 return 值,我能够比较键和 return 键,但我无法比较值和 return 键。怎么办?

谢谢!

dict1.Union(dict2)
    .GroupBy(kvp => kvp.Value)
    .Where(g => g.Count() > 1) // but this doesn't account for equal values in same dictionary if that's important
    .Select(g => new
    {
        Value = g.Key,
        Keys = g.Select(kvp => kvp.Key),
    });

或者,您可以加入每个字典的 KeyValuePair<TKey,TValue> 个对象的 Value 属性。

您可以创建自己的 IEqualityComparer 并使用需要它的 Intersect 重载。

static void Main(string[] args)
{
    var dict1 = new Dictionary<int, (int, int)>();
    dict1.Add(1, (1, 1));
    dict1.Add(2, (2, 2));
    dict1.Add(3, (3, 3));
    var dict2 = new Dictionary<int, (int, int)>();
    dict2.Add(4, (2, 2));
    dict2.Add(5, (3, 3));
    dict2.Add(6, (4, 4));

    var intersection = dict1.Intersect(dict2, new eq());

    foreach (var i in intersection)
        Console.WriteLine($"Key: {i.Key}, Value: {i.Value}");
    Console.ReadLine();
}

class eq : IEqualityComparer<KeyValuePair<int, (int, int)>>
{
    public bool Equals(KeyValuePair<int, (int, int)> x, KeyValuePair<int, (int, int)> y)
    {
        return x.Value == y.Value;
    }

    public int GetHashCode(KeyValuePair<int, (int, int)> obj)
    {
        unchecked
        {
            int hash = 17;
            hash = hash * 23 + obj.Value.Item1;
            hash = hash * 23 + obj.Value.Item2;
            return hash;
        }
    }
}

Key: 2, Value: (2, 2)
Key: 3, Value: (3, 3)

来自 Jon Skeet this answer 的散列

您可以简单地使用 Where 过滤器并检查其他字典是否包含值:

var matches = dict1.Where(d => dict2.ContainsValue(d.Value));

这将 return 一个可枚举的,然后您可以根据需要使用 ToDictionary()ToList()

编辑:

使用这个 Union 到 return 比赛双方:

dict1.Where(d => dict2.ContainsValue(d.Value))
     .Union(dict2.Where(d => dict1.ContainsValue(d.Value)));

HTH