ikeru
![devDependencies Status](https://david-dm.org/vinsonchuong/ikeru/dev-status.svg)
The art of arranging data
Usage
Install ikeru
by running:
yarn add ikeru
BinarySearchTree
A sorted dictionary of number keys to arbitrary values.
Note that these trees do not self-balance. See RedBlackTree
.
import { get, set, remove, entries } from 'ikeru/binary-search-tree'
let tree
tree = set(tree, 5, { title: 'Five' })
tree = set(tree, 3, { title: 'Three' })
tree = set(tree, 7, { title: 'Seven' })
console.log(get(tree, 1))
for (const node of entries(tree)) {
console.log(node.key, node.title)
}
console.log(JSON.stringify(tree, null, 2))
tree = remove(tree, 5)
for (const node of entries(tree)) {
console.log(node.key, node.value)
}
RedBlackTree
A BinarySearchTree
that self-balances after every update,
maintaining O(log n)
reads and writes.
RedBlackTree
follows the same interface as BinarySearchTree
.
import { get, set, remove, entries } from 'ikeru/red-black-tree'
let tree
tree = set(tree, 5, { title: 'Five' })
tree = set(tree, 3, { title: 'Three' })
tree = set(tree, 7, { title: 'Seven' })
for (const node of entries(tree)) {
console.log(node.key, node.title)
}
TimeSeries
ikeru
provides various utilities for summarizing and transforming time series
data.
import {
merge, downsample, interpolate, extrapolate, window, join
} from 'ikeru/time-series'
import {
getMonth, startOfMonth, differenceInDays, addDays, addMonths, subMonths
} from 'date-fns'
const series1 = [
{ time: Date.parse('2019-01-01') },
{ time: Date.parse('2019-02-03') },
{ time: Date.parse('2019-03-07') }
]
const series2 = [
{ time: Date.parse('2019-01-02') },
{ time: Date.parse('2019-02-04') },
{ time: Date.parse('2019-03-08') }
]
const series3 = [
{ time: Date.parse('2019-01-05') },
{ time: Date.parse('2019-02-06') },
{ time: Date.parse('2019-03-09') },
{ time: Date.parse('2019-05-03') }
]
const series = merge(series1, series2, series3)
const monthlyMissingApril = downsample(
series,
point => startOfMonth(point.time).getTime(),
(time, points) => ({ time })
)
const monthly = interpolate(
monthlyMissingApril,
(before, after) => {
const newPoints = []
let point = before
while (differenceInDays(after.time, point.time) > 1) {
point = {
time: addDays(point.time, 1).getTime()
}
newPoints.push(point)
}
return newPoints
}
)
const everyMonthInYear = extrapolate(
monthly,
start => {
const newPoints = []
let point = start
while (getMonth(point.time) > 0) {
point = subMonths(point, 1)
newPoints.push(point)
}
newPoints.reverse()
return newPoints
},
end => {
const newPoints = []
let point = end
while (getMonth(point.time) < 11) {
point = addMonths(point.time, 1)
newPoints.push(point)
}
return newPoints
}
)
const firstThreeMonths = window(
everyMonthInYear,
Date.parse('2019-01-01'),
Date.parse('2019-03-31')
)
const parallelSeries1 = [
{ time: Date.parse('2019-01-01'), value: 1 },
{ time: Date.parse('2019-01-02'), value: 2 },
{ time: Date.parse('2019-01-03'), value: 3 }
]
const parallelSeries2 = [
{ time: Date.parse('2019-01-01'), value: 4 },
{ time: Date.parse('2019-01-02'), value: 5 },
{ time: Date.parse('2019-01-03'), value: 6 }
]
const addedUp = join([parallelSeries1, parallelSeries2], (time, [p1, p2]) => ({
time,
value: p1.value + p2.value
}))