【问题标题】:Two-way key value collection [duplicate]双向键值收集[重复]
【发布时间】:2018-09-04 08:24:01
【问题描述】:

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

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]

【问题讨论】:

  • 你有 LINQ。
  • 如果您不太关心性能,一个简单的 .Where() 就可以完成这项工作
  • 另一个选项是数据表。它不关心方向,可以使用索引来提高性能
  • 您应该使用键值对列表。 var collection = new List&lt;KeyValuePair&lt;int, string&gt;&gt;();这个你可以很容易地用LINQ查询。
  • @Linuxrocks 不需要使用 KVP,元组数组也可以工作

标签: c# dictionary collections


【解决方案1】:

使用TupleList&lt;Tuple&lt;int,string&gt;&gt; 允许具有相同键的集合和LINQ 对您的集合进行查询Where

例如,

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

【讨论】:

    【解决方案2】:

    这是一种解决方案,可让您在两个方向上进行字典查找。我假设您想忽略重复的元组,并且默认比较器就足够了。实现像 Remove 之类的其他操作留给读者练习

    public class TwoWayCollection<A, B>
    {
        private Dictionary<A, HashSet<B>> byADictionary = new Dictionary<A, HashSet<B>>();
        private Dictionary<B, HashSet<A>> byBDictionary = new Dictionary<B, HashSet<A>>();
    
        public IEnumerable<B> 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<B>();
            }
            byADictionary[a].Add(b);
            if (!byBDictionary.ContainsKey(b))
            {
                byBDictionary[b] = new HashSet<A>();
            }
            byBDictionary[b].Add(a);
        }
    }
    

    然后使用它实际上是您建议的代码。根据字典,Get 和 InverseGet 都接近 O(1)

    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]
    

    【讨论】:

      猜你喜欢
      • 2021-09-25
      • 2019-07-15
      • 1970-01-01
      • 2021-10-25
      • 2021-11-04
      • 2019-03-19
      • 1970-01-01
      • 2020-12-08
      • 2019-06-17
      相关资源
      最近更新 更多