当前位置:  开发笔记 > 编程语言 > 正文

在C#中,有没有开箱即用的方法来构建3向查找表?

如何解决《在C#中,有没有开箱即用的方法来构建3向查找表?》经验,为你挑选了3个好方法。

我有一个内存"表",可能看起来像这样:

Favorite#  Name        Profession
---------  ----------  ------------------
3          Names.Adam  Profession.Baker
9          Names.Bob   Profession.Teacher
7          Names.Carl  Profession.Coder
7          Names.Dave  Profession.Miner
5          Names.Fred  Profession.Teacher

我想做的是使用3个字段中的任何一个进行快速有效的查找.换句话说,我想:

myTable[3]myTable[Names.Adam]myTable[Professions.Baker]所有的回报{3,Names.Adam,Profession.Baker}

myTable[Profession.Teacher]返回{9,Names.Bob,Profession.Teacher}{5,Names.Fred,Profession.Teacher}.

该表是在运行时根据用户的操作构建的,并且不能存储在数据库中,因为它在无法保证数据库连接的部分中使用.

现在,我"简单地"(哈!)使用3个超级字典存储它,每个字符使用其中一个列(FavoriteNumber,Name,Profession)键入,并且uber-Dictionaries中的每个值包含2个字典,这些字典本身都是键入的每个剩余的列(因此"名称"超级字典中的值属于类型DictionaryDictionary

这需要2个字典中的2个查找,以及数组的另一个遍历(通常包含1或2个元素.)

任何人都可以提出更好的方法吗?我不介意花费额外的内存,因为表可能很小(不超过20个条目)但我愿意牺牲一点CPU来使它更容易维护代码......



1> Nick Berardi..:

然而,并不是真的使用字典,但是如果你创建这样的类的集合

class Person {
    public int FavoriteNumber;
    public string Name;
    public string Profession;
}

您可以使用LINQ搜索集合.

IList people = /* my collection */;
var selectedPeople = people.Where(p => p.FavoriteNumber = 3);
var selectedPeople2 = people.Where(p => p.Name == "Bob");
var selectedPeople3 = people.Where(p => p.Profession = "Teacher");

或者如果您更喜欢普通的LINQ语法

var selectedPeople4 = from p in people
                      where p.Name == "Bob"
                      select p;

这些selectedPeople变量中的每一个都将被输入IEnumerable,您可以使用循环来搜索它们.



2> Marc Gravell..:

对于20行,只需使用线性扫描 - 它在各方面都是最有效的.

对于较大的集合; hzere是一种使用LINQ ToLookup和延迟索引的方法:

public enum Profession {
    Baker, Teacher, Coder, Miner
}
public class Record {
    public int FavoriteNumber {get;set;}
    public string Name {get;set;}
    public Profession Profession {get;set;}
}
class Table : Collection
{
    protected void Rebuild()
    {
        indexName = null;
        indexNumber = null;
        indexProfession = null;
    }
    protected override void ClearItems()
    {
        base.ClearItems();
        Rebuild();
    }
    protected override void InsertItem(int index, Record item)
    {
        base.InsertItem(index, item);
        Rebuild();
    }
    protected override void RemoveItem(int index)
    {
        base.RemoveItem(index);
        Rebuild();
    }
    protected override void SetItem(int index, Record item)
    {
        base.SetItem(index, item);
        Rebuild();
    }
    ILookup indexNumber;
    ILookup indexName;
    ILookup indexProfession;
    protected ILookup IndexNumber {
        get {
            if (indexNumber == null) indexNumber = this.ToLookup(x=>x.FavoriteNumber);
            return indexNumber;
        }
    }
    protected ILookup IndexName {
        get {
            if (indexName == null) indexName = this.ToLookup(x=>x.Name);
            return indexName;
        }
    }
    protected ILookup IndexProfession {
        get {
            if (indexProfession == null) indexProfession = this.ToLookup(x=>x.Profession);
            return indexProfession;
        }
    }
    public IEnumerable Find(int favoriteNumber) { return IndexNumber[favoriteNumber]; }
    public IEnumerable Find(string name) { return IndexName[name]; }
    public IEnumerable Find(Profession profession) { return IndexProfession[profession]; }
}



3> plinth..:

我认为这样做的方法是编写自己的对象

public ICollection this[int] { get; }
public ICollection this[Profession] { get; }
public ICollection this[Names] { get; }

其中record是一个包含元素的类.

在内部,你保留一个List,每个索引器都有List.FindAll()来获得你需要的东西.

推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有