C# 结合字典+字典创建字典

C# 结合字典+字典创建字典,c#,dictionary,C#,Dictionary,在内部联接样式中,有没有什么很酷的快速方法可以使用两个字典创建第三个字典,将第一个字典的键映射到第二个字典的值 Dictionary<A,B> dic1 = new Dictionary<A,B> {{a1,b1},{a2,b2},{a3,b3}}; Dictionary<B,C> dic2 = new Dictionary<B,C> {{b1,c1},{b2,c2},{b4,c4}}; Dictionary<A,C> dic3 =

在内部联接样式中,有没有什么很酷的快速方法可以使用两个字典创建第三个字典,将第一个字典的键映射到第二个字典的值

Dictionary<A,B> dic1 = new Dictionary<A,B> {{a1,b1},{a2,b2},{a3,b3}};
Dictionary<B,C> dic2 = new Dictionary<B,C> {{b1,c1},{b2,c2},{b4,c4}};

Dictionary<A,C> dic3 = SomeFunction(dic1,dic2);
// dic3 = {{a1,c1},{a2,c2}}

我相信这会满足你的需求

也许是与ToDictionary有关的东西

dic1.Where(d1=>dic2.ContainsKey(d1.Value)).ToDictionary(d1=>d1.Key,d1=>dic2[d1.Value]);

您可以这样做来加入内部值

Dictionary<int, string> first = new Dictionary<int, string> { {1, "hello"}, {2, "world"}};

Dictionary<string, bool> second = 
    new Dictionary<string, bool> { { "hello", true }, {"world", false}};

var result = (from f in first
              join s in second on f.Value equals s.Key
              select new { f.Key, s.Value }).ToDictionary(x => x.Key, y => y.Value);
如果您转储结果,您将看到它是一个值为{1:true,2:false}的字典

Dictionary<string, string> a, b, c;

//code to initialize the 3 dictionaries. a,b are original dictionaries and c is the new dictionary

c = ( from ak in a.Keys
    where b.ContainsKey( ak )
    select new KeyValuePair<string, string>( ak, b[ ak ] ) ).ToDictionary( d => d.Key, d=> d.Value );
处理dic2不包含与dic1s值对应的键而不存储伪空值的情况,IMO非常清楚。我确实喜欢一些LINQ,但我想我会给出一次程序性的答案…

最简单的解决方案:

        Dictionary<int, string> dic1 = new Dictionary<int,string>();
        Dictionary<string, decimal> dic2 = new Dictionary<string,decimal>();

        dic1.Add(1, "one");
        dic1.Add(2, "two");
        dic1.Add(3, "three");
        dic1.Add(4, "four");
        dic1.Add(5, "five");

        dic2.Add("one",1.0m);
        dic2.Add("two", 2.0m);
        dic2.Add("three", 3.0m);
        dic2.Add("four", 4.0m);
        dic2.Add("five", 5.0m);


        Dictionary<int, decimal> result = (from d1 in dic1
                                           from d2 in dic2
                                           where d1.Value == d2.Key
                                           select new { d1.Key, d2.Value }).ToDictionary(p=>p.Key, p=>p.Value);
var dict3 = dict1.ToDictionary(p => p.Key, p => dict2[p.Value]);

你想让这本新词典上线吗?也就是说,如果你做了dic3,然后有人改变了dic1和dic2中的值,dic3的行为会改变吗?我下面的回答将你的问题解释为本质上的内部连接,但也许你想要的是左外部连接还是右外部连接?您能澄清一下吗?@Eric-我的意图是非实时使用。@Roly-q更新为指定内部联接+1我最喜欢这个,因为它实际上处理了dic2在dic1中缺少值键的情况。它通过添加null作为对应键的值来实现这一点。不确定这是否是期望的行为。@Domenic:因为TS没有说明他是否希望包含空值,所以这似乎是最好的。我还注意到,这并没有检查dic2中是否有未添加的值,但在这里,TS也没有说明。问题是,您无法区分来自dic2的null与由于dic2没有该键的值而产生的null之间的区别。如果dic1中有任何Bs不在dic2中,则会爆炸,-1。好的,但现在它添加了null,这是不好的,因为null是存储在字典中的有效值,不能用作缺少值的符号;我对join还不够熟悉,不知道它是否有效。你能让我放心吗+我不确定它是如何实现的,但我可以想象,如果第二个字典没有排序,它将在Om*n时间内运行,其中m和n分别是左字典和右字典的大小。但我不认为这与其他解决方案有什么不同,它们在第一个字典上有一个for循环,在第二个字典上有一个where子句。感谢Roly,这看起来很棒。字典通过O1查找实现为哈希表。Join假设被联接的序列不是快速查找表,因此它用其中一个序列构建自己的快速查找表。因此,此解决方案的时间效率并不比原始解决方案高,并且在其操作过程中可能会产生大量垃圾。有趣。那么,这个假设是否仅限于连接,或者其他LINQ操作也会受到这个假设的影响?这是否有效,因为它是将键与键进行比较,而不是将键与值进行比较?@Mike-我想他想要的是一个1到2映射值的键,已经编辑了我的答案。thnxI认为问题在于连接,他还希望将值从1连接到键2。
        Dictionary<int, string> dic1 = new Dictionary<int,string>();
        Dictionary<string, decimal> dic2 = new Dictionary<string,decimal>();

        dic1.Add(1, "one");
        dic1.Add(2, "two");
        dic1.Add(3, "three");
        dic1.Add(4, "four");
        dic1.Add(5, "five");

        dic2.Add("one",1.0m);
        dic2.Add("two", 2.0m);
        dic2.Add("three", 3.0m);
        dic2.Add("four", 4.0m);
        dic2.Add("five", 5.0m);


        Dictionary<int, decimal> result = (from d1 in dic1
                                           from d2 in dic2
                                           where d1.Value == d2.Key
                                           select new { d1.Key, d2.Value }).ToDictionary(p=>p.Key, p=>p.Value);
var dict3 = dict1.ToDictionary(p => p.Key, p => dict2[p.Value]);