【问题标题】:What is a good data structure to use for holding two values?用于保存两个值的好的数据结构是什么?
【发布时间】:2011-12-11 03:41:34
【问题描述】:

例如,我在我的应用程序中有一个类型列表,该列表以人名作为其名称并包含两个值。类型的名称是人名,类型仅包含他们的年龄和标准数量。

我的第一个想法是创建一个具有 Age 和 NumStds 属性的 Persons 类,其中在构造函数中需要 Age 和 NumStds,并创建一个我可以添加到的 List。

class Person
{
    public string Name { get; set; }
    public int NumSTDs { get; set; }
    public int Age { get; set; }

    public Person(string name, int age, int stds)
    {
        Name = name;
        Age = age; 
        NumSTDs = stds; 
    }
}

static void Main(string[] args)
{
    List<Person> peoples = new List<Person>();
    peoples.Add(new Person("Julie", 23, 45)); 
}

我只是想知道是否有一个数据结构,我可以通过它们的名称引用 List 中的元素,并让附加到它们的属性随之而来。就像我可以说的那样

people.Remove(Julie) 

【问题讨论】:

  • 如果有两个同名的人怎么办?

标签: c# data-structures


【解决方案1】:

听起来您正在寻找Dictionary

Dictionary<string, Person> peoples = new Dictionary<string, Person>();
Person oPerson = new Person("Julie", 23, 45); 
peoples.Add(oPerson.Name, oPerson); 

另一个选项是System.Collections.ObjectModel.KeyedCollection。这需要更多的工作来实现,但可能很有用。

要完成这项工作,请为 person 创建一个集合类并覆盖 GetKeyForItem 方法:

public class PersonCollection : System.Collections.ObjectModel.KeyedCollection<string, Person>
{
    protected override string GetKeyForItem(Person item)
    {
        return item.Name;
    }
}

然后您可以将项目添加到集合中,如您的示例所示:

PersonCollection peoples = new PersonCollection();
peoples.Add(new Person("Julie", 23, 45));

然后删除项目:

peoples.Remove("Julie");

【讨论】:

    【解决方案2】:

    看看KeyedCollection<TKey, TValue> Class

    KeyedCollection

    为其键嵌入在值中的集合提供抽象基类。

    你需要从这个抽象类派生出你自己的集合类,例如

    class PersonCollection : KeyedCollection<string, Person>
    {
        protected override string GetKeyForItem(Person item)
        {
            return item.Name;
        }
    }
    

    例子:

    static void Main(string[] args)
    {
        var peoples = new PersonCollection();
        var julie = new Person("Julie", 23, 45)
        peoples.Add(julie);
    
        people.Remove(julie);
        //  - or -
        people.Remove("Julie");
    }
    

    请注意,您的 Person 类的 Name 属性应该是不可变的(只读)。

    【讨论】:

      【解决方案3】:

      我不确定您的要求,但只要看看您帖子末尾的 Remove() 语句,您可以使用 linq 表达式获得相同的效果。

      people.Remove(p => string.Compare(p.Name, "Julia", true) == 0);
      

      【讨论】:

      • 使用 string.Equals() 而不是 string.Compare()
      【解决方案4】:

      为此使用Dictionary&lt;string, Person&gt; 的问题是您可能拥有与人名不匹配的密钥。这可以避免,但我宁愿使用HashSet&lt;Person&gt; 来完成这项工作。性能是一样的。

      您只需要通过覆盖GetHashCode 来准备您的课程以返回Name 的哈希码。

      public override int GetHashCode()
      {
          return Name.GetHashCode();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-09
        • 2012-02-03
        • 1970-01-01
        • 2011-01-05
        • 2019-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多