Comparing version 1.8.0 to 1.9.0
{ | ||
"name": "dodos", | ||
"version": "1.8.0", | ||
"version": "1.9.0", | ||
"description": "Pandas-inspired iterator-based data wrangling library for js", | ||
@@ -5,0 +5,0 @@ "main": "dist/dodos.js", |
106
src/dodo.js
import invariant from 'invariant' | ||
import zip from 'lodash/zip' | ||
import zipObject from 'lodash/zipObject' | ||
import clone from 'lodash/clone' | ||
import unzip from 'lodash/unzip' | ||
@@ -14,3 +14,3 @@ const MAP_ACTION = 'MAP_ACTION' | ||
const meta = Symbol('meta') | ||
const dispatch = Symbol('dispatch') | ||
const dispatchReduce = Symbol('dispatchReduce') | ||
const noActions = [] | ||
@@ -51,9 +51,2 @@ | ||
[dispatch](method, fn, init) { | ||
if (this[index] == Arrays.get(this).index) | ||
return this[method](fn, init) | ||
else | ||
return this[method + 'Each'](fn, init) | ||
} | ||
[action](action) { | ||
@@ -76,6 +69,13 @@ return new Dodo(Arrays.get(this), [...this.actions, action]) | ||
let lastRowIndex = ArraysMetadata.get(array).length - 1 | ||
let rowIndex | ||
// TODO: if there is a slice before any filter | ||
// set rowIndex to slice.start - 1 | ||
let rowIndex = -1 | ||
const firstNonMap = this.actions | ||
.filter(act => act.type != MAP_ACTION) | ||
.slice(0, 1) | ||
if (firstNonMap.type == SLICE_ACTION) | ||
rowIndex = firstNonMap.start - 1 | ||
else | ||
rowIndex = -1 | ||
while (rowIndex++ < lastRowIndex) { | ||
@@ -178,45 +178,46 @@ let row = array[rowIndex] | ||
reduce(fn, init) { | ||
invariant(init != null, `Dodo#reduce(fn, init) - init is required`) | ||
[dispatchReduce](args) { | ||
if (this[index] == Arrays.get(this).index) | ||
return this.reduce(...args()) | ||
else | ||
return this._reduceEach(args) | ||
} | ||
reduce(fn, init, final=identity) { | ||
invariant(init != null, `Dodo#reduce(fn, init, final) - init is required`) | ||
invariant(fn && typeof fn == 'function', | ||
`Dodo#reduce(fn) — fn not a function`) | ||
`Dodo#reduce(fn, init, final) — fn not a function`) | ||
for (const row of this) | ||
init = fn(init, row) | ||
return init | ||
return final === identity ? init : final(init) | ||
} | ||
reduceEach(fn, init) { | ||
const len = Object.keys(this[index]).length | ||
const fns = Array(len).fill(fn) | ||
const inits = fns.map(() => clone(init)) | ||
_reduceEach(args) { | ||
const [fns, inits, finals] = unzip(this[names].map(() => args())) | ||
return zipObject( | ||
this[names], | ||
this.reduce(combineReducers(fns, true), inits) | ||
this.reduce(combineReducers(fns, true), inits, spread(finals)) | ||
) | ||
} | ||
count() { return this[dispatch]('reduce', ...REDUCERS.count) } | ||
stats(...methods) { | ||
const args = () => { | ||
const [fns, inits, finals] = zip(...methods.map(m => REDUCERS[m]())) | ||
return [combineReducers(fns), inits, spread(finals)] | ||
} | ||
return this[dispatchReduce](args) | ||
} | ||
sum() { return this[dispatch]('reduce', ...REDUCERS.sum) } | ||
count() { return this[dispatchReduce](REDUCERS.count) } | ||
min() { return this[dispatch]('reduce', ...REDUCERS.min) } | ||
sum() { return this[dispatchReduce](REDUCERS.sum) } | ||
max() { return this[dispatch]('reduce', ...REDUCERS.max) } | ||
min() { return this[dispatchReduce](REDUCERS.min) } | ||
mean() { | ||
const stats = this.stats('count', 'sum') | ||
if (Array.isArray(stats)) { | ||
return stats[1] / stats[0] | ||
} else { | ||
for (const name of Object.keys(stats)) | ||
stats[name] = stats[name][1] / stats[name][0] | ||
return stats | ||
} | ||
} | ||
max() { return this[dispatchReduce](REDUCERS.max) } | ||
stats(...methods) { | ||
const [fns, inits] = zip(...methods.map(m => REDUCERS[m])) | ||
return this[dispatch]('reduce', combineReducers(fns), inits) | ||
} | ||
countUniq() { return this[dispatchReduce](REDUCERS.countUniq) } | ||
mean() { return this[dispatchReduce](REDUCERS.mean) } | ||
groupBy(name, fn) { | ||
@@ -234,2 +235,13 @@ invariant(name, `Dodo#groupBy(name, fn) - name is required`) | ||
const spread = (fns) => { | ||
const len = fns.length | ||
return value => { | ||
let i = len | ||
while (i--) { | ||
value[i] = fns[i](value[i]) | ||
} | ||
return value | ||
} | ||
} | ||
const combineReducers = (fns, spread) => { | ||
@@ -256,7 +268,15 @@ const len = fns.length | ||
const identity = a => a | ||
const REDUCERS = { | ||
max: [(max, el) => max > el ? max : el, -Infinity], | ||
min: [(min, el) => min < el ? min : el, Infinity], | ||
sum: [(sum, el) => sum + el, 0], | ||
count: [count => ++count, 0], | ||
max: () => [(max, el) => max > el ? max : el, -Infinity, identity], | ||
min: () => [(min, el) => min < el ? min : el, Infinity, identity], | ||
sum: () => [(sum, el) => sum + el, 0, identity], | ||
mean: () => [ | ||
([count, sum], el) => [++count, sum + el], | ||
[0, 0], | ||
([count, sum]) => sum / count | ||
], | ||
count: () => [count => ++count, 0, identity], | ||
countUniq: () => [(set, el) => set.add(el), new Set(), set => set.size], | ||
} | ||
@@ -263,0 +283,0 @@ |
@@ -311,3 +311,3 @@ import test from 'ava' | ||
test('reduce over multiple columns', t => { | ||
test.skip('reduce over multiple columns', t => { | ||
const dodo = new Dodo(table) | ||
@@ -334,2 +334,3 @@ const cols = Object.keys(Index) | ||
['mean', arr => _.mean(arr)], | ||
['countUniq', arr => new Set(arr).size], | ||
] | ||
@@ -354,4 +355,9 @@ const col = 'Date' | ||
t.same( | ||
dodo.col(col).stats('sum', 'count'), | ||
[dodo.col(col).sum(), dodo.col(col).count()] | ||
dodo.col(col).stats('sum', 'count', 'mean', 'countUniq'), | ||
[ | ||
dodo.col(col).sum(), | ||
dodo.col(col).count(), | ||
dodo.col(col).mean(), | ||
dodo.col(col).countUniq() | ||
] | ||
) | ||
@@ -365,2 +371,8 @@ t.same( | ||
) | ||
t.same( | ||
dodo.cols(cols).stats(...shorthands.map(s => s[0])), | ||
_.zipObject(cols, | ||
cols.map(col => dodo.col(col).stats(...shorthands.map(s => s[0]))) | ||
) | ||
) | ||
}) | ||
@@ -367,0 +379,0 @@ |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
0
126483
2270