Объекты против массивов в Javascript для пар ключ/значение
Скажем, у вас очень простая структура данных:
(personId, name)
... и вы хотите сохранить несколько из них в переменной javascript. Как я вижу, у вас есть три варианта:
// a single object
var people = {
1 : 'Joe',
3 : 'Sam',
8 : 'Eve'
};
// or, an array of objects
var people = [
{ id: 1, name: 'Joe'},
{ id: 3, name: 'Sam'},
{ id: 8, name: 'Eve'}
];
// or, a combination of the two
var people = {
1 : { id: 1, name: 'Joe'},
3 : { id: 3, name: 'Sam'},
8 : { id: 8, name: 'Eve'}
};
Вторая или третья опция - это, очевидно, путь, если у вас есть (или ожидаете, что у вас может быть) более одной части "значение" для хранения (например, добавление их возраста или чего-то еще), так что ради аргумента, предположим, что в этой структуре никогда не будет больше значений данных. Какой из них вы выбираете и почему?
Изменить. Пример теперь показывает наиболее распространенную ситуацию: не последовательные идентификаторы.
Ответы
Ответ 1
Каждое решение имеет свои варианты использования.
Я думаю, что первое решение хорошо, если вы пытаетесь определить отношения "один-к-одному" (например, простое сопоставление), особенно если вам нужно использовать ключ в качестве ключа поиска.
Второе решение кажется самым надежным для меня в целом, и я бы, вероятно, использовал его, если мне не нужен быстрый ключ поиска:
- Это самоописание, поэтому вы не
должны зависеть от тех, кто использует
чтобы знать, что ключ является идентификатором пользователя.
- Каждый объект приходит автономно,
который лучше для передачи данных
в другом месте - вместо двух параметров
(id и имя) вы просто проходите
человек.
- Это редкая проблема, но иногда
значения ключа могут быть недействительными для
использовать как ключи. Например, один раз
хотел сопоставить преобразования строк
(например, ":" до " > " ), но поскольку ":"
не является допустимым именем переменной, которой я должен был
используйте второй метод.
- Он легко расширяется, в случае
где-то вдоль линии вам нужно
добавьте больше данных некоторым (или всем) пользователям.
(Извините, я знаю о вашем "для
аргумент ради ", но это
важный аспект.)
Третий хороший, если вам нужно быстрое время поиска + некоторые из преимуществ, перечисленных выше (передача данных вокруг, самоописание). Однако, если вам не нужно быстрое время поиска, это намного более громоздко. Кроме того, в любом случае вы рискуете ошибкой, если идентификатор в объекте каким-то образом отличается от идентификатора в людях.
Ответ 2
На самом деле есть четвертый вариант:
var people = ['Joe', 'Sam', 'Eve'];
так как ваши значения являются последовательными. (Конечно, вам придется добавить/вычесть один или просто поместить undefined в качестве первого элемента).
Лично я бы пошел с вашими (1) или (3), потому что они будут быстрее всего искать кого-то по ID (O log n в худшем случае). Если вам нужно найти id 3 в (2), вы можете просмотреть его по индексу (в этом случае my (4) в порядке), или вам нужно выполнить поиск - O (n).
Разъяснение: я говорю, что O (log n) хуже всего, потому что AFAIK и реализация могут решить использовать сбалансированное дерево вместо хеш-таблицы. Хэш-таблица была бы O (1), предполагая минимальные столкновения.
Отредактируйте с nickf: с тех пор я изменил пример в OP, так что этот ответ, возможно, больше не имеет смысла. Извинения.
После редактирования
Хорошо, после редактирования, я бы выбрал вариант (3). Он расширяемый (легко добавлять новые атрибуты), обеспечивает быстрый поиск и может быть также повторен. Он также позволяет вам перейти от входа обратно к идентификатору, если вам нужно.
Вариант (1) был бы полезен, если (а) вам нужно сохранить память; (б) вам не нужно переходить с объекта обратно на id; (c) вы никогда не будете расширять сохраненные данные (например, вы не можете добавить фамилию человека)
Вариант (2) хорош, если вы (а) должны сохранять порядок; (b) необходимо перебрать все элементы; (c) не нужно искать элементы по id, если только он не сортируется по id (вы можете выполнить двоичный поиск в O (log n). Обратите внимание, что, если вам нужно сохранить он сортируется, тогда вы будете оплачивать затраты на вставку.
Ответ 3
Предполагая, что данные никогда не будут меняться, первый вариант (один объект) является лучшим.
Простота структуры означает, что она наиболее быстро анализируется, и в случае небольших, редко (или никогда) изменяющихся наборов данных, таких как эта, я могу только представить, что она будет часто выполняться - в этом случае минимальная накладные расходы - это путь.
Ответ 4
Я создал небольшую библиотеку для управления парами значений ключей.
https://github.com/scaraveos/keyval.js#readme
Он использует
- объект для хранения ключей, который позволяет быстро удалять и извлекать значения
операций и
- связанный список, позволяющий действительно быстрое итерацию значений
Надеюсь, это поможет:)
Ответ 5
Третий вариант является лучшим для любого перспективного приложения. Вероятно, вы захотите добавить в свою запись больше полей, поэтому первый вариант не подходит. Кроме того, очень вероятно, что у вас будет большое количество людей для хранения, и вам захочется быстро найти записи - таким образом, сброс их в простой массив (как это делается в варианте № 2) тоже не является хорошей идеей.
Третий шаблон дает вам возможность использовать любую строку в качестве идентификатора, иметь сложные структуры Person и получать и устанавливать записи людей в постоянное время. Это определенно путь.
Одна вещь, которой не удовлетворяет опция № 3, - это стабильное детерминированное упорядочение (что является опцией варианта № 2). Если вам это нужно, я бы рекомендовал хранить упорядоченный массив идентификаторов лиц как отдельную структуру, когда вам нужно будет перечислить людей в порядке. Преимущество состоит в том, что вы можете хранить несколько таких массивов для разных порядков одного и того же набора данных.
Ответ 6
Учитывая ваше ограничение, что вы только когда-либо будете иметь имя в качестве значения, я бы выбрал первый вариант. Это самое чистое, имеет наименьшее издержки и быстрый поиск.