Object Array Transposer(y) - JS objects with multiple key/value structures
The idea (j-m's) was to find a way of being able to get values from an array of objects in O(1) time, in an environment where memory isn't an issue.
For example, I could have the following JS object:
const food = [
{
id: 1,
name: "apple",
type: "fruit",
},
{
id: 2,
name: "orange",
type: "fruit",
},
{
id: 3,
name: "broccoli",
type: "vegetable",
},
];
As-is, to get the item where the id is 3, I'd use food.find(x => x.id === 3)
or similar.
If the array was transposed to use id
as object keys, the resultant object would look like the following:
const foodById = {
1: {
id: 1,
name: "apple",
type: "fruit",
},
2: {
id: 2,
name: "orange",
type: "fruit",
},
3: {
id: 3,
name: "broccoli",
type: "vegetable",
},
};
This way, we can get the food with the id
of 3 with foodById[3]
.
However, we don't know that object keys will all be unique, so objects should be placed in arrays. For example:
const foodByType = {
fruit: [
{
id: 1,
name: "apple",
type: "fruit",
},
{
id: 2,
name: "orange",
type: "fruit",
},
],
vegetable: [
{
id: 3,
name: "broccoli",
type: "vegetable",
},
],
};
Now, to get an array of fruit, rather than using food.filter(f => f.type === 'fruit')
we can just use foodByType['fruit']
.
For data that changes frequently, this is a bad approach since transposing the data to use different key values is expensive.
However, for data that is assigned once (e.g. when a server first starts running) or assigned relatively infrequently (e.g. polling a database) this idea should be far less CPU-intensive than frequently searching the array using filter
, find
, or manually.
This library's default export is OatyArray
. Initialise it as such:
const oatyFood = new OatyArray(food, { keys: ["id", "type"] });
In the above case, food
is the initial array of items and ['id', 'type']
is the array of keys you want to be able to query.
The OatyArray
constructor generates the transposed caches.
To query data, use the get
method:
const fruitArray = oatyFood.get("type", "fruit");
The above is effectively the same as foodByType['fruit']
in the above examples
oaty
is built with Typescript
To get started, run npm install
to install dependencies.
npm test
npm run build
Feel free to open Issues/PRs with suggestions/problems/improvements.
Library is versioned as-per the semver standard.
1.0.0
new OatyArray([{ myKey: "myValue" }])
without needing to provide a type.keys
input is now enforced to a subset of the keys of the given typekeys
input will now be used to enforce that only valid objects are transposed by Oaty.keys
will now always return either an array containing all the auto transposed keys, or an array of the configured keys, and is now type correct..push
meaning that an error will be thrown at compile time if an invalid object is being passed to Oaty..get
to return the correct types depending on usagetypescript@3.8
tsd
tests0.4.0
new OatyArray<T>()
so that .get
, .data
, and .transposed
return data of type T
. This is completely optional as T
defaults to any
.missingKeyReturns
and noResultsReturns
options._transposed
property.data
constructor param optional and default to []
..get
searches for that key, it will now throw a ReferenceError
.0.3.0
get
s for data
, keys
, and transposed
keys
optional - will transpose every (root) key in an object.get()
is undefinedoriginal
to data
.get()
can now retrieve all objects that have a key, like .get('fruit')
0.2.1
.get()
method type (object[]
)0.2.0
OatyObject
to OatyArray
, since it's intended as an array alternative, rather than an object alternative0.1.0
.push
function0.0.0