Именование словарной структуры, которая хранит ключи в предсказуемом порядке?

Примечание. Хотя мой конкретный контекст Objective-C, мой вопрос фактически выходит за рамки выбора языка программирования. Кроме того, я отметил его как "субъективный", так как кто-то обязан жаловаться иначе, но я лично считаю его почти полностью объективным. Кроме того, я знаю этот связанный вопрос SO, но поскольку это была большая проблема, я подумал, что лучше сделать это отдельным вопросом. Пожалуйста, не критикуйте вопрос, не читая и не понимая его полностью. Спасибо!

Большинство из нас знакомо с словарь абстрактный тип данных, в котором хранятся ассоциации ключевых значений, независимо от того, назовите это картой, словарем, ассоциативным массивом, хешем и т.д. в зависимости от нашего выбора. Простое определение словаря можно суммировать тремя свойствами:

  • Доступ к значениям осуществляется с помощью ключа (в отличие от индекса, например массива).
  • Каждая клавиша связана со значением.
  • Каждый ключ должен быть уникальным.

Любые другие свойства, возможно, являются удобствами или специализациями для определенной цели. Например, некоторые языки (особенно языки сценариев, такие как PHP и Python) размывают линию между словарями и массивами и обеспечивают упорядочение словарей. Насколько это возможно, такие дополнения не являются фундаментальными характеристиками словаря. В чистом смысле фактические детали реализации словаря не имеют значения.

По моему вопросу, самое важное наблюдение заключается в том, что порядок перечисления ключей не определен. Словарь может предоставлять ключи в любом удобном для него порядке, и это зависит от того, чтобы организовать их по желанию.

Я создал пользовательские словари, которые налагают определенные порядки клавиш, в том числе упорядоченные по естественному порядку (на основе сравнения объектов) и порядок вставки. Очевидно, чтобы назвать прежний вариант на SortedDictionary (который я уже реализовал), но последний более проблематичен. Я видел LinkedHashMap и LinkedMap (Java), OrderedDictionary (.NET), OrderedDictionary (Flash), OrderedDict (Python) и OrderedDictionary (Objective-C). Некоторые из них более зрелые, некоторые из них более доказательны.

LinkedHashMap назван в соответствии с реализацией традиций коллекций Java - "связан", потому что он использует дважды связанный список для отслеживания порядка вставки и "хэш", потому что он подклассифицирует HashMap. Помимо того, что пользователю не нужно беспокоиться об этом, имя класса на самом деле даже не указывает, что он делает. Использование упорядоченного похоже на консенсус между существующим кодом, но веб-поиск по этой теме также выявил понятную путаницу между "упорядоченными" и "отсортированными", и я чувствую то же самое. В реализации .NET даже есть комментарий о кажущемся неправильном значении, и предполагается, что вместо этого он должен быть "IndexedDictionary" из-за того, что вы можете извлекать и вставлять объекты в определенную точку в упорядочении.

Я разрабатываю фреймворк и API, и я хочу назвать класс максимально разумным. С моей точки зрения, индексированный, вероятно, будет работать (в зависимости от того, как люди его интерпретируют и на основе рекламируемой функциональности словаря) упорядоченный является неточным и имеет слишком большой потенциал для путаница и связанный "(извинитесь за Monty Python).; -)

Как пользователь, какое имя будет иметь для вас наибольший смысл? Есть ли конкретное имя, которое точно говорит о том, что делает класс? (Я не прочь использовать несколько более длинные имена, такие как InsertionOrderDictionary, если это необходимо.)

Изменить: Еще одна сильная возможность (обсуждаемая в моем ответе ниже) - IndexedDictionary. Мне не очень нравится "порядок вставки", потому что это не имеет смысла, если вы разрешаете пользователю вставлять ключи по определенному индексу, изменять порядок ключей и т.д.

Ответ 1

Я голосую OrderedDictionary по следующим причинам:

"Индексированный" никогда не используется в классах Cocoa, кроме одного экземпляра. Он всегда отображается как существительное (NSIndexSet, NSIndexPath, objectAtIndex:, и т.д.). Существует только один экземпляр, когда "Индекс" отображается как глагол, который находится в свойстве "индексированное" NSPropertyDescription: isIndexed и setIndexed. NSPropertyDescription примерно аналогична столбцу таблицы в базе данных, где "индексирование" относится к оптимизации для ускорения времени поиска. Поэтому было бы разумно, что с использованием NSPropertyDescription, являющегося частью структуры основных данных, "isIndexed" и "setIndexed" будет эквивалентно индексу в базе данных SQL. Поэтому назвать его "IndexedDictionary" представляется избыточным, поскольку индексы в базах данных создаются для ускорения времени поиска, но словарь уже имеет O (1) время поиска. Однако назвать его "IndexDictionary" также было бы неправильным, так как "индекс" в Cocoa относится к позиции, а не к порядку. Эти два семантически отличаются.

Я понимаю вашу обеспокоенность по поводу "OrderedDictionary", но прецедент уже установлен в Cocoa. Когда пользователи хотят поддерживать определенную последовательность, они используют "упорядоченные": - [NSApplication orderedDocuments], - [NSWindow orderedIndex], - [NSApplication orderedWindows] и т.д. Итак, у Джона Пири в основном правильная идея.

Однако вы не хотите вставлять в словарь нагрузку на своих пользователей. Они захотят создать словарь один раз, а затем поддерживать соответствующий порядок. Они даже не захотят запрашивать объекты в определенном порядке. Спецификация заказа должна быть выполнена во время инициализации.

Поэтому я рекомендую сделать OrderedDictonary кластер класса с частными подклассами InsertionOrderDictionary и NaturalOrderDictionary и CustomOrderDictionary. Затем пользователь просто создает OrderedDictionary следующим образом:

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

Для CustomOrderDictionary вы можете заставить их выбрать селектор сравнения или даже (если они работают 10.6) блок. Я думаю, что это обеспечит максимальную гибкость для будущего расширения, сохранив при этом соответствующее имя.

Ответ 2

Я проголосую за InsertionOrderDictionary. Вы прибили его.

Ответ 3

Сильное голосование за OrderedDictionary.

Слово "упорядочено" означает именно то, что вы рекламируете: при итерации по списку элементов существует определенный порядок выбора этих элементов. "Индексированный" - это слово реализации - он больше говорит о том, как выполняется заказ. Индекс, связанный список, дерево... пользователю все равно; этот аспект структуры данных должен быть скрыт. "Ordered" - точное слово для дополнительной функции, которую вы предлагаете, независимо от того, как вы это сделаете.

Кроме того, кажется, что выбор заказа может быть у пользователя. Любая причина, по которой вы не можете создавать методы в вашем типе данных, которые позволяют пользователю переключаться, скажем, в алфавитном порядке на порядок ввода-времени? В случае по умолчанию пользователь выбирает конкретный заказ и придерживается его, и в этом случае реализация будет не менее эффективной, чем если бы вы создали специализированные подклассы для каждого метода упорядочения. И в некоторых менее используемых случаях разработчик действительно может использовать любое из нескольких разных порядков для одних и тех же данных, в зависимости от контекста приложения. (Я могу думать о конкретных проектах, над которыми я работал, где бы мне хотелось, чтобы такая структура данных была доступна.)

Назовите это OrderedDictionary, потому что это точно, что это такое. (Честно говоря, у меня больше проблемы с употреблением слова "Словарь", потому что это слово в значительной степени подразумевает упорядочение, где популярные реализации такого рода не предоставляют его, но что мой питомец завидует. Вы действительно должны просто быть в состоянии скажем, "Словарь" и знать, что упорядочение является алфавитным - потому что это то, что словарь IS - но этот аргумент слишком поздно для существующих реализаций на популярных языках.) И разрешить пользователю доступ в том порядке, который он выбирает.

Ответ 4

После публикации этого вопроса я начинаю склоняться к чему-то вроде IndexedDictionary или IndexableDictionary. Хотя полезно иметь возможность поддерживать произвольный порядок клавиш, ограничение того, что порядок вставки выглядит просто как ненужное ограничение. Кроме того, мой класс уже поддерживает indexOfKey: и keyAtIndex:, которые (целенаправленно) аналогичны NSArray indexOfObject: и objectAtIndex:. Я настоятельно рекомендую добавить insertObject:forKey:atIndex:, который соответствует NSMutableArray insertObject:atIndex:.

Всем известно, что вставка в середине массива неэффективна, но это не значит, что нам не следует позволять в редких случаях, что это действительно полезно. (Кроме того, реализация может тайно использовать дважды связанный список или любую другую подходящую структуру для отслеживания заказа при необходимости...)

Большой вопрос: "индексируется" или "индексируется" как неопределенное или потенциально запутанное как "упорядоченное"? Будут ли люди думать о индексах базы данных, о книжных индексах и т.д.? Было бы вредно, если бы они предположили, что он был реализован с помощью массива или может упростить понимание пользователем функциональности?


Изменить: Это имя имеет еще большее значение, учитывая тот факт, что я рассматриваю возможность добавления методов, которые работают с NSIndexSet в будущем. (NSArray имеет -objectsAtIndexes:, а также методы добавления/удаления наблюдателей для объектов с заданными индексами.)

Ответ 5

Как насчет KeyedArray?

Ответ 6

Как вы сказали в своем последнем абзаце, я считаю, что InsertionOrder (ed) Dict (ionary) довольно однозначен; Я не вижу, как это можно интерпретировать каким-либо образом, кроме того, что ключи будут возвращены в том порядке, в котором они были вставлены.

Ответ 7

На первый взгляд я с первым ответом - InsertionOrderDictionary, хотя это немного двусмысленно относительно того, что означает "InsertionOrder" на первый взгляд.

То, что вы описываете, звучит для меня почти так же, как карта С++ STL. Из того, что я понимаю, карта - это словарь, который имеет дополнительные правила, включая порядок. STL просто называет это "картой", что, я думаю, довольно уместно. Трюк с картой заключается в том, что вы не можете наделить наследование кивком, не делая его излишним - т.е. "MapDictionary". Это слишком избыточно. "Карта" немного слишком полезна и оставляет много места для неправильной интерпретации.

Хотя "CHMap" может быть неудачным выбором после просмотра вашей документации.

Может быть, "CHMappedDictionary"? =)

Желаем удачи.

Изменить: Спасибо за разъяснение, вы узнаете что-то новое каждый день. =)

Ответ 8

Развязывая индексированный порядок от порядка вставки, разве это просто не сводится к тому, чтобы хранить массив и словарь в одном объекте? Я думаю, мой голос за этот тип объекта IndexedKeyDictionary

В С#:

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
  }
}

Что было бы здорово, это индексированные значения... так что у нас есть способ отсортировать значения и получить новый порядок ключей. Как если бы значения были координатами графа, и мы могли читать ключи (имена бинов) при движении вверх/вниз вдоль координатной плоскости. Что бы вы назвали этой структурой данных? IndexedValueDictionary?

Ответ 9

Единственное отличие, что allKeys возвращает ключи в определенном порядке? Если это так, я просто добавлю методы allKeysSorted и allKeysOrderdByInsertion к стандартному API NSDictionary.

Какова цель этого словаря для заказа вставки? Какие преимущества дает программист против массива?