什么是用于保存两个值的好数据结构?

6
例如,在我的应用程序中,有一个列表类型,名称为人名,包含两个值。该类型的名称是人名,仅包含他们的年龄和标准数量。
我的第一个想法是创建一个具有年龄和NumStds属性的Persons类,其中Age和NumStds在构造函数中是必需的,然后创建一个列表以便可以添加到其中。
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) 

2
如果有两个人同名怎么办? - TrueWill
4个回答

5

听起来你正在寻找一个词典

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

另一个选项是System.Collections.ObjectModel.KeyedCollection。这需要更多的工作来实现,但可以很有用。
为了使其工作,创建一个人员集合类并重写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");

1

请查看KeyedCollection<TKey, TValue>类

KeyedCollection<TKey, TValue>类

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

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

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属性应该是不可变的(只读)。

1

我不确定您的要求是什么,但仅查看您在帖子末尾的Remove()语句,您可以使用Linq表达式获得相同的效果。

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

2
使用 string.Equals() 而不是 string.Compare()。 - slugster

0
使用 Dictionary<string, Person> 的问题在于,您可能会有一个键与人的名称不匹配。虽然可以避免这种情况,但我更愿意使用 HashSet<Person> 来完成工作。性能相同。
您只需要准备好您的类,通过重写 GetHashCode 方法返回 Name 的哈希码即可。
public override int GetHashCode()
{
    return Name.GetHashCode();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接