Подтвердить что ты не робот

Объекты против массивов в 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'}
};

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


Изменить. Пример теперь показывает наиболее распространенную ситуацию: не последовательные идентификаторы.

4b9b3361

Ответ 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

Учитывая ваше ограничение, что вы только когда-либо будете иметь имя в качестве значения, я бы выбрал первый вариант. Это самое чистое, имеет наименьшее издержки и быстрый поиск.