【问题标题】:Hash table with two primary keys具有两个主键的哈希表
【发布时间】:2011-06-09 00:40:42
【问题描述】:

使用System.Collections如何创建具有两个主键的集合?

我的意思是避免使用相同组合的新条目,但每个键都可以与其他键一起使用(例如在 SQL 中组合两个主键)

【问题讨论】:

  • 我认为您正在寻找的术语是复合键或复合键。具有两个属性的键仍然只是一个键,而不是两个。

标签: c# collections primary-key hashtable


【解决方案1】:

你也可以构造复合键并在字典中使用它

var compositeKey = key1.ToString()+key2.ToString();

var dict = new Dictionary<string,object>();
dict.Add(compositekey,val);

【讨论】:

    【解决方案2】:

    就像 LaGrandMere 所说,如果您使用 .NET 4.0 或更高版本,则可以使用 System.Tuple

    Tuple<int,string> key = Tuple.Create(0, "Test");
    

    另外,请注意,如果您将字符串、整数等作为键放入字典中,您将不得不对 SQL 中为 NULL 的内容进行特殊处理。字典中不能有空键。

    var dict = new Dictionary<Tuple<string, int>, string>();
    
    var address1 = Tuple.Create("5th Avenue",15);
    var address2 = Tuple.Create("5th Avenue",25);
    var address3 = Tuple.Create("Dag Hammarskjölds väg", 4);
    
    dict[address1] = "Donald";
    dict[address2] = "Bob";
    dict[address3] = "Kalle";
    
    // ...
    
    int number = Int32.Parse("25");
    var addressKey = Tuple.Create("5th Avenue",number);
    string name = dict[addressKey]; // Bob
    

    【讨论】:

      【解决方案3】:

      如果您使用的是 .NET 4.0,则可以使用 Tuple

      否则你可以自己创建一个元组。

      在 StackOverFlow 上找到:Tuples( or arrays ) as Dictionary keys in C#

      struct Tuple<T, U, W> : IEquatable<Tuple<T,U,W>>
      {
          readonly T first;
          readonly U second;
          readonly W third;
      
          public Tuple(T first, U second, W third)
          {
              this.first = first;
              this.second = second;
              this.third = third;
          }
      
          public T First { get { return first; } }
          public U Second { get { return second; } }
          public W Third { get { return third; } }
      
          public override int GetHashCode()
          {
              return first.GetHashCode() ^ second.GetHashCode() ^ third.GetHashCode();
          }
      
          public override bool Equals(object obj)
          {
              if (obj == null || GetType() != obj.GetType())
              {
                  return false;
              }
              return Equals((Tuple<T, U, W>)obj);
          }
      
          public bool Equals(Tuple<T, U, W> other)
          {
              return other.first.Equals(first) && other.second.Equals(second) && other.third.Equals(third);
          }
      }
      

      【讨论】:

        【解决方案4】:

        您可以简单地使用struct,例如:

        struct CompositeKey<T1,T2>
        {
          public T1 Item1;
          public T2 Item2;
        }
        

        然后用它作为键。

        【讨论】:

        • 请注意,如果出于性能原因使用字典,结构可能无法按预期工作。请参阅“How does native implementation of ValueType.GetHashCode work?”。
        • @johv:哈希码不必是唯一的,.NET 也可以非常快地处理一些冲突。许多碰撞显然会成为一个问题。
        • 我发现结构的默认实现非常令人惊讶且不直观。我曾期待更接近元组提供的东西。
        • @johv:然后我们也可以比较匿名类型 :) 我的方法只是展示一个非常简单的方法,它应该在 95% 的时间里都很好。
        • 但这真的是“95% 的好时间”吗?如何计算具有两个字符串的结构的哈希码?只使用第一个字符串?我猜你是正确的,如果 95% 的时间,你的意思是线性搜索访问时间还可以。
        猜你喜欢
        • 2019-05-03
        • 1970-01-01
        • 2011-06-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-11
        • 1970-01-01
        • 2012-07-31
        • 1970-01-01
        相关资源
        最近更新 更多