命名存储在可预知的顺序键的字典结构?(Naming a dictionary structure t

2019-07-29 01:46发布

注:虽然我的特定情况下是Objective-C的,我的问题其实超越了编程语言的选择。 另外,我已被标签为“主观的”,因为有人势必否则抱怨,但我个人认为这是几乎完全客观。 此外,我所知道的这个相关的SO问题 ,但由于这是一个比较大的问题,我想还是让这个独立的问题。 请没有阅读并充分理解它不批评的问题。 谢谢!

我们大多数人都熟悉的字典抽象数据类型存储键值协会,我们是否把它的地图,字典,关联数组,哈希等,这取决于我们的选择的语言。 字典的简单定义可以通过三个属性来概括:

  1. 值由按键可以访问(如由指数而非,如阵列)。
  2. 每个键与一个值。
  3. 每个键必须是唯一的。

任何其他属性是针对特定用途可以说是便利或专门化。 例如,一些语言(特别是脚本语言,例如PHP和Python)模糊词典和阵列之间的线和不提供排序为字典。 如,因为这可以是有用的,这样的添加不是词典的一个基本特征。 在一个纯粹意义上的,一本字典的实际执行的细节是无关紧要的。

对于我的问题,最重要的发现是, 在按键被列举的顺序是没有定义 -字典可以提供一切为了找到最方便的按键,它是由客户端根据需要组织起来。

我创建的自定义词典强加特定键排序,包括自然排序的顺序 (基于对象的比较),并插入顺序 。 这是显而易见的名字SortedDictionary(这我实际上已经实施)前的一些变种,但是后者更成问题。 我见过的LinkedHashMap和LinkedMap (渣), OrderedDictionary (.NET), OrderedDictionary (闪存), OrderedDict (蟒蛇),和OrderedDictionary (Objective-C的)。 其中有些是比较成熟的,有一些是比较验证的概念。

因为它的子类HashMap的“链接”,因为它采用的是双向链表来追踪广告订单和“散列” - LinkedHashMap的是根据Java集合的传统执行命名。 除了这个事实,用户不应该需要担心的是,类名并没有真正甚至表示它做什么。 使用命令看起来像现有代码的共识,但关于这一主题的网络搜索还透露,“有序”和“分类”之间的理解混乱,我有同样的感觉。 在.NET实现甚至有对明显用词不当评论,并建议它应该是“IndexedDictionary”代替,因为事实上,你可以检索和在订购的特定点插入对象。

我设计一个框架,API和我想的聪明地将类命名。 从我的角度来看, 指数可能会工作(这取决于人们如何解读它,并基于字典的通告功能), 是不精确的,有太多的潜在的混乱,并链接 “是正确的了”(道歉巨蟒)。 ;-)

作为用户,什么样的名字会做出最有意义吗? 有没有说完全类做什么特定的名称? (我不反对使用像InsertionOrderDictionary如果合适稍长的名字。)

编辑:另一种强大的可能性(在我的回答如下讨论)是IndexedDictionary。 我真的不喜欢“插入顺序”,因为,如果你允许用户在指定索引插入钥匙就没有意义了,重新排序键等

Answer 1:

我投OrderedDictionary,有以下原因:

“索引”是从来没有在Cocoa类中,除了一个实例。 它总是显示为一个名词(的NSIndexSet,NSIndexPath,objectAtIndex:等)。 只有当“指数”显示为一个动词,这是NSPropertyDescription的“索引”属性一个实例:isIndexed和setIndexed。 NSPropertyDescription是大致类似于在数据库中的表的列,其中,“索引”指的是最优化,以加快搜索时间。 因此它将使意义与NSPropertyDescription作为核心数据框架的一部分,即“isIndexed”和“setIndexed”就相当于在一个SQL数据库的索引。 因此,把它称为“IndexedDictionary”就显得多余,因为在数据库索引创建要加快查找时间,但一本字典已经有O(1)查找时间。 然而,把它称为“IndexDictionary”也将是一个用词不当,因为一个“指数”可可指的位置,而不是命令。 两者是不同语义。

我明白了“OrderedDictionary”你的关心,但先例已经在可可被设置。 当用户希望保持一个特定的顺序,他们使用 “命令”: - [的NSApplication orderedDocuments] - [NSWindow orderedIndex] - [的NSApplication orderedWindows]等,所以,约翰·皮里大多正确的想法。

但是,你不想做插入词典中的负担压在你的用户。 他们会想创建一个字典一次 ,然后让它保持适当的顺序。 他们甚至不会想请求按照特定的顺序对象。 为了规范应在初始化时进行。

因此,我建议在做OrderedDictonary类集群,以InsertionOrderDictionary和NaturalOrderDictionary和CustomOrderDictionary的私有子类。 然后,用户只是简单地创建了以下这样一个OrderedDictionary:

OrderedDictionary * dict = [[OrderedDictionary alloc] initWithOrder:kInsertionOrder];
//or kNaturalOrder, etc

对于CustomOrderDictionary,你可以让他们给你一个比较选择,甚至(如果他们正在运行10.6)块。 我认为这将提供最大的灵活性,为将来的扩展,同时仍然保持一个合适的名称。



Answer 2:

我投InsertionOrderDictionary 。 你钉它。



Answer 3:

强投票OrderedDictionary。

单词“订购”是指你的广告真正:在通过项目列表迭代,有一个定义为这些项目的选择。 “索引”是一个实现词 - 它更多的排序是如何实现的。 指数,链表,树...该用户并不关心; 的数据结构的这一方面应该被隐藏。 “有序”是附加特征中的确切的词你提供,无论你如何完成它。

此外,它似乎是选择订购可根据用户的选择。 任何理由,你为什么不能创建,允许用户从,说,字母顺序切换到插入时间顺序上的数据类型的方法呢? 在默认情况下,用户会选择一个特定的顺序,并坚持下去,在这种情况下实施不会比,如果你创建了专门的子类为每个排序方法效率较低。 而在一些较少使用的情况下,开发者实际上可能希望使用任意数量的不同排序中的相同数据,这取决于应用程序上下文。 (我想我在哪里,我会喜欢有可用这样的数据结构工作的具体项目。)

说它OrderedDictionary,因为这是它正是。 (坦白地说,我有更多的使用单词“字典”的问题,因为这个词沉重暗示排序,其中的一些流行的实现不提供了,但是这是我的忌讳。你真的应该只能够说“字典”,并知道排序是按字母顺序排列 - 因为这是一个字典是什么 - 但这样的说法是在流行的语言现有实现太晚了),并允许用户在他选择什么样的顺序访问。



Answer 4:

由于张贴这个问题,我开始对类似IndexedDictionaryIndexableDictionary倾斜。 虽然它是能够保持任意键排序,从而限制了对插入排序有用的,只有似乎是一个不必要的限制。 另外,我的课已经支持indexOfKey:keyAtIndex:这是(故意)analagous到NSArray的indexOfObject:objectAtIndex: 我强烈考虑增加insertObject:forKey:atIndex:与NSMutableArray里的相匹配insertObject:atIndex:

大家都知道,在阵列中的中间插入是低效的,但是,这并不意味着我们不应该被允许在罕见的情况下,它是真正有用的。 (此外,实现可以偷偷使用双向链表或者如果需要跟踪的顺序任何其他合适的结构...)

最大的问题:在“索引”或“可转位”那样的模糊或可能造成混淆的是“有序”? 人们会认为数据库索引,或书索引等的? 难道是有害的,如果他们认为这是一个数组实现的,也可能是简化的功能,用户理解?


编辑:这名因为我正在考虑添加方法与一个工作的事实就更有道理的NSIndexSet的未来。 (NSArray的具有-objectsAtIndexes:以及用于添加/以给定的索引移除的对象观察员方法)



Answer 5:

什么KeyedArray?



Answer 6:

当你在最后一段说,我认为InsertionOrder(ED)词典(ionary)是非常明确的; 我看不出它如何能在比键会在他们被插入的顺序返回其他任何方式进行解释。



Answer 7:

通过从插入订单分离索引顺序,不这仅仅归结为保持阵列和字典中的单个对象? 我想我对这种类型的对象投票IndexedKeyDictionary

在C#:

public class IndexedKeyDictionary<TKey, TValue> { 

  List<TKey> _keys;
  Dictionary<TKey, TValue> _dictionary;
  ...

  public GetValueAtIndex(int index) {
    return _dictionary[_keys[index]];
  }

  public Insert(TKey key, TValue val, int index) {
    _dictionary.Add(key, val);

    // do some array massaging (splice, etc.) to fit the new key
    _keys[index] = key;
  }

  public SwapKeyIndexes(TKey k1, TKey k2) {
    // swap the indexes of k1 and k2, assuming they exist in _keys
  }
}

什么是真正的酷是索引值......所以我们有办法的值进行排序,并获得新的键顺序。 就像如果值分别为图形的坐标,我们可以读出键(BIN名),我们向上沿坐标平面/向下。 你会调用数据结构? 一个IndexedValueDictionary?



Answer 8:

乍一看我与第一个回复 - InsertionOrderDictionary,虽然这是一个有点暧昧,什么“InsertionOrder”是指乍一看。

什么你所描述的声音,我几乎完全与C ++ STL的地图。 从我的理解,地图是具有附加规则,包括订购一本字典。 STL的只是称其为“地图”,我认为这是相当贴切。 地图的技巧是,你真的不能给继承点头没有使它多余的 - 即“MapDictionary”。 这只是过于冗余。 “地图”是有点太基本的和留下了很多的曲解。

虽然“CHMap”可能不是在看你的文档链接后,一个坏的选择。

也许 “CHMappedDictionary”? =)

祝您好运。

编辑:感谢您的澄清,你每天学习新的东西。 =)



Answer 9:

Is the only difference that allKeys returns keys in a specific order? If so, I would simply add allKeysSorted and allKeysOrderdByInsertion methods to the standard NSDictionary API.

What is the goal of this insertion order dictionary? What benefits does it give the programmer vs. an array?



文章来源: Naming a dictionary structure that stores keys in a predictable order?