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.
- Run tests:
npm test
- Build:
npm run build
Feel free to open Issues/PRs with suggestions/problems/improvements.
Library is versioned as-per the semver standard.
- Added extra type inference and enforcement to Oaty, this means that an array can be initialised
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.- Oaty will now enforce the correct keys are the objects of
.push
meaning that an error will be thrown at compile time if an invalid object is being passed to Oaty. - Updated overloads on
.get
to return the correct types depending on usage - Updated to
[email protected]
- Added
tsd
tests
- Oaty can now be initialised with
new OatyArray<T>()
so that.get
,.data
, and.transposed
return data of typeT
. This is completely optional asT
defaults toany
. - Removed
missingKeyReturns
andnoResultsReturns
options. - Exported a new type for the
_transposed
property. - Expanded the ternary conditions to improve readability.
- Made the
data
constructor param optional and default to[]
. - When a key is not transposed and
.get
searches for that key, it will now throw aReferenceError
. - Added NYC and increased tests to 100% coverage.
- Added
get
s fordata
,keys
, andtransposed
- Made
keys
optional - will transpose every (root) key in an object - Added two options to change the return value for when they key or value of
.get()
is undefined - Renamed
original
todata
.get()
can now retrieve all objects that have a key, like.get('fruit')
- Added simple benchmark
- Added more tests
- Fixed
.get()
method type (object[]
)
- Renamed
OatyObject
toOatyArray
, since it's intended as an array alternative, rather than an object alternative - Named export, rather than default export
- Added
.push
function
- Initial proof of concept