首先,这可能是一个XY问题,对不起。
我正在从文件加载文件表并将其放入内存中的文件树中。树中的节点表示树中的目录/文件。目前,我每个节点使用两个数据结构,由于插入到集合中而导致明显的加载时间,并且由于重复字符串数据和引用每个节点两次而导致更高的内存使用量。树木被装载一次,之后不会发生变异。
每个节点都有一个用于访问已排序子节点的List和一个用于按名称访问子节点的Dictionary。由于性能原因,该列表被懒惰地排序。 SortedDictionary不符合我的使用要求,因为我需要将子节点放在没有子节点的节点之上,因此传递IComparer是不够的。当两个节点都有/没有子节点时,它们按字典顺序排序(OrdinalIgnoreCase)。
.net中是否有满足我需求的数据结构?
另外,是否有任何方法可以在插入字典时为密钥提供哈希值,以及稍后从字典中获取一部分桶(即:GetValuesByHash(int hashValue))相应键具有给定散列的所有值)?我正在读取的文件表已经包含整个文件路径的哈希值(适用于我正在做的另一件事),而且目前,字典只是无缘无故地重新计算它们。
我认为我可以通过定义我自己的自定义键来解决一个解决方案,其中包含{Hash,Node}和自定义比较器,但这看起来真的很难看,而且你无法获得共享相同节点的桶哈希值。如果有的话,那仍然会感觉使用错误的数据结构。
我已经使用Google搜索“c#dictionary get hash”以及其他一些查询,但此时我还没有看到任何类似的问题。
总体而言,寻找具有以下属性的数据结构(可能与字典相关):
条目分类如下:
m_children.Sort(
(a, b) => {
bool aHasChildren = a.HasChildren;
bool bHasChildren = b.HasChildren;
if (aHasChildren && !bHasChildren)
return 1;
if (!aHasChildren && bHasChildren)
return -1;
else
return -String.Compare(a.m_resourceName, b.m_resourceName, StringComparison.OrdinalIgnoreCase);
}
);
可以按上述排序顺序检索所有子节点。目前,我有一个ChildrenSorted和ChildrenUnsorted属性。由于排序,ChildrenSorted属性可能会受到影响,而ChildrenUnsorted属性则不会。
我认为更糟糕的是,我的解决方案是编写自己的类字典类。我不必从字典中删除键,所以它应该不难。不过,我有点想避免这样做。
我的节点实施可在以下位置查看:http://pastie.org/5547925
谢谢!
答案 0 :(得分:1)
我认为您的解决方案已经非常好了。以下是一些想法:
"d1\d2\filename"
或string[]
之类的路径。点(2)将是RDBMS如何做到的。
答案 1 :(得分:0)
您只需将SortedDictionary
lambda放入“IComparer:
Sort()
public class MyComparer : IComparer, IComparer<MyNode>
{
public int Compare(object x, object y)
{
return Compare(x as MyNode, y as MyNode);
}
public int Compare(MyNode x, MyNode y)
{
if (ReferenceEquals(x, y))
{
return 0;
}
if (ReferenceEquals(x, null))
{
return -1;
}
if (ReferenceEquals(y, null))
{
return 1;
}
bool xHasChildren = x.HasChildren;
bool yHasChildren = y.HasChildren;
if (xHasChildren && !yHasChildren)
return 1;
if (!xHasChildren && yHasChildren)
return -1;
else
return String.Compare(y.m_resourceName, x.m_resourceName, StringComparison.OrdinalIgnoreCase);
}
}