Dmitry Dmitry - 1 year ago 48
Javascript Question

javascript/json storing strictly indexed arrays

I am trying to describe a Pokemon move "database" with javascript to practice data description.

I have a bunch of moves, identified by an id(number)., name(string), and type(string).

I want to create a javascript array of moves such as this(use array index as id for O(1) lookup by id):

const moves = [
{name: 'Astonish', type: 'Ghost'},
{name: 'Constrict', type: 'Normal'},
{name: 'Acid', type: 'Poison'},
{name: 'Ingrain', type: 'Grass'}

However, I want to ensure that the index of these entries is strictly positioned(to avoid pasting an entry into the start of the array, invalidating the indexes, as well as making it more explicit what the entries are so you don't need to do a linear search to find the item each time you look at the list.

What I want to do is this, but it is not supported by JavaScript syntax:

const moves = [
0: {name: 'Astonish', type: 'Ghost'},
1: {name: 'Constrict', type: 'Normal'},
2: {name: 'Acid', type: 'Poison'},
3: {name: 'Ingrain', type: 'Grass'}

Doing this by explicitly inserting each item seems expensive and visually annoying:

const moves = [];

/* anonymous scope: setup moves */
moves[0] = {name: 'Astonish', type: 'Ghost'};
moves[1] = {name: 'Constrict', type: 'Normal'},
moves[2] = {name: 'Acid', type: 'Poison'},
moves[3] = {name: 'Ingrain', type: 'Grass'}

I could use an object, but objects are more expensive than arrays for this kind of behavior. I could also create an object then map it into an array like this:

const moves = (() => {
let res = [];
let tmp = {
0: {name: 'Astonish', type: 'Ghost'},
1: {name: 'Constrict', type: 'Normal'},
2: {name: 'Acid', type: 'Poison'},
3: {name: 'Ingrain', type: 'Grass'}
Object.keys(tmp).map ((key) => {
res[key] = tmp[key];

return res;

but it seems a tad silly.

The reason why I want to have array index as id is because it would both be fast to access, and make it easy to make another object to map back the move names to their id(for O(1) move by name lookup).

Is there a way to describe this kind of array in a more coherent way, or are these the only options I have without inventing my own javascript convention, preprocessor?

Thanks ahead of time.

Answer Source

There are more drawbacks:

  • If your move IDs are implicitly given by their array index (and you want to keep your array an ordinary linear storage array) you are not allowed to have 'holes' in the ID range without wasting space.
  • If you remove a move, you have to slice the array which is (assuming a linear storage array) no longer in O(1) and shifts all succeeding IDs.
  • If you allow gaps in your ID range e.g. by inserting moves[3] = ...; moves[5] = ...; or by deleting an array entry, your array will be 'deoptimized', i.e. no longer a linear storage array but a map.

To avoid all these issues and still have O(1) comp. complexity (unless your JS engine is really quirky) for insertion, access and removal, use a map. Either the ES6 Map or a plain old Object.