The ideas in this post are implemented in the keyed-array package on npm.
Imagine you're building a JSON webservice that will return a collection of people. Each person is an object:
id: 'bob'name: 'Bob'isCool: false
You could structure the JSON response as an array:
people =id: 'bob' name: 'Bob' isCool: falseid: 'sue' name: 'Sue' isCool: falseid: 'hal' name: 'Hal' isCool: trueid: 'ann' name: 'Ann' isCool: true
This is nice because Arrays have lots of methods for dealing with collections, like
sort. Gathering up the names of all the cool people is pretty easy:
But when you want a person with a specific id, you have to do something like this:
Kind of cumbersome. A simple
people.bob would be more convenient.
Instead of storing the id in the object, use it as a key:
people =bob: name: 'Bob' isCool: falsesue: name: 'Sue' isCool: falsehal: name: 'Hal' isCool: trueann: name: 'Ann' isCool: true
The nice thing about this structure is that you can easily access a person if you know their id:
The drawback of this structure is that it's more cumbersome to iterate over an Object than an Array. The code for fetching the names of cool people now looks like this:
Not so great.
Here's the crazy idea: Use an Array of person objects, but iterate over it once at load time, assigning a key for each person's id:
This way it's still an array:
Array // => truepeople0name // => Bobpeoplelength // => 4
But there's now a named key for each person, so content is now addressable by id:
peoplebobisCool // => true'sue' in people // => true
This is kind of the best of both worlds, but there are a few drawbacks.
Object.keys(people).length is no longer reliable, as it returns both the numeric keys of the array and the named keys we assigned:
Object// => ['0', '1', '2', '3', 'bob', 'sue', 'hal', 'ann']
JSON.stringify will produce undesirable results. But if those two drawbacks are not important for your use case, this little technique could fit your needs.