关于c#:双向键值集合

Two-way key value collection

本问题已经有最佳答案,请猛点这里访问。

C中是否有一个集合像字典一样工作,具有多个允许双向访问的键?例如:

1
2
3
4
5
6
Collection<int, string> a = new Collection<int, string>();
a.Add(1,"a");
a.Add(1,"b");
a.Add(2,"a");
a.Get(1);//returns ["a","b"]
a.InverseGet("a"); //returns [1, 2]


使用tuple List>允许具有相同密钥的集合和LINQ查询到集合的位置

例如,

1
2
3
4
5
6
7
List<Tuple<int,string>> list = new List<Tuple<int,string>>();
list.Add(Tuple.Create(23,"Foo"));
list.Add(Tuple.Create(23,"Bar"));
list.Add(Tuple.Create(25,"Bar"));

var keys = list.Where(x=> x.Item1 == 23).Select(x=> x.Item2); // FOO, BAR
var values = list.Where(x=> x.Item2 =="Bar").Select(x=> x.Item1); ; // 23, 25

这里有一个解决方案,可以让您在两个方向上执行字典查找。我假设您希望忽略重复的元组,并且默认比较器就足够了。实现诸如remove之类的其他操作留给读者作为练习。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class TwoWayCollection<A, B>
{
    private Dictionary<A, HashSet> byADictionary = new Dictionary<A, HashSet>();
    private Dictionary<B, HashSet<A>> byBDictionary = new Dictionary<B, HashSet<A>>();

    public IEnumerable Get(A a)
    {
        return byADictionary[a];
    }

    public IEnumerable<A> InverseGet(B b)
    {
        return byBDictionary[b];
    }

    public void Add(A a, B b)
    {
        if (!byADictionary.ContainsKey(a))
        {
            byADictionary[a] = new HashSet();
        }
        byADictionary[a].Add(b);
        if (!byBDictionary.ContainsKey(b))
        {
            byBDictionary[b] = new HashSet<A>();
        }
        byBDictionary[b].Add(a);
    }
}

那么,使用它实际上就是您建议的代码。根据字典的get和inverseget方法o(1)

1
2
3
4
5
6
TwoWayCollection<int, string> a = new TwoWayCollection<int, string>();
a.Add(1,"a");
a.Add(1,"b");
a.Add(2,"a");
a.Get(1); //returns ["a","b"]
a.InverseGet("a"); //returns [1, 2]