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
例如,
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] |