From f0c13de5384c4ee966bbab4253db474924d1adec Mon Sep 17 00:00:00 2001 From: max Date: Mon, 11 Mar 2024 11:18:27 -0400 Subject: [PATCH 1/4] Added an optional options parameter to the toArray method of the data series in order to allow a caller to include explicit null values. --- src/lib/series.ts | 1182 ++++++++++++++++++++------------------- src/test/series.test.ts | 23 + 2 files changed, 615 insertions(+), 590 deletions(-) diff --git a/src/lib/series.ts b/src/lib/series.ts index b8ebc55..f137735 100644 --- a/src/lib/series.ts +++ b/src/lib/series.ts @@ -1,20 +1,20 @@ -import { ArrayIterable } from './iterables/array-iterable'; -import { EmptyIterable } from './iterables/empty-iterable'; -import { CountIterable } from './iterables/count-iterable'; -import { MultiIterable } from './iterables/multi-iterable'; -import { SelectIterable } from './iterables/select-iterable'; -import { SelectManyIterable } from './iterables/select-many-iterable'; -import { TakeIterable } from './iterables/take-iterable'; -import { TakeWhileIterable } from './iterables/take-while-iterable'; -import { WhereIterable } from './iterables/where-iterable'; -import { ConcatIterable } from './iterables/concat-iterable'; -import { SeriesWindowIterable } from './iterables/series-window-iterable'; -import { ReverseIterable } from './iterables/reverse-iterable'; -import { ZipIterable } from './iterables/zip-iterable'; -import { DistinctIterable } from './iterables/distinct-iterable'; -import { SeriesRollingWindowIterable } from './iterables/series-rolling-window-iterable'; -import { SeriesVariableWindowIterable } from './iterables/series-variable-window-iterable'; -import { OrderedIterable, Direction, ISortSpec, SelectorFn as SortSelectorFn } from './iterables/ordered-iterable'; +import { ArrayIterable } from './iterables/array-iterable'; +import { EmptyIterable } from './iterables/empty-iterable'; +import { CountIterable } from './iterables/count-iterable'; +import { MultiIterable } from './iterables/multi-iterable'; +import { SelectIterable } from './iterables/select-iterable'; +import { SelectManyIterable } from './iterables/select-many-iterable'; +import { TakeIterable } from './iterables/take-iterable'; +import { TakeWhileIterable } from './iterables/take-while-iterable'; +import { WhereIterable } from './iterables/where-iterable'; +import { ConcatIterable } from './iterables/concat-iterable'; +import { SeriesWindowIterable } from './iterables/series-window-iterable'; +import { ReverseIterable } from './iterables/reverse-iterable'; +import { ZipIterable } from './iterables/zip-iterable'; +import { DistinctIterable } from './iterables/distinct-iterable'; +import { SeriesRollingWindowIterable } from './iterables/series-rolling-window-iterable'; +import { SeriesVariableWindowIterable } from './iterables/series-variable-window-iterable'; +import { OrderedIterable, Direction, ISortSpec, SelectorFn as SortSelectorFn } from './iterables/ordered-iterable'; import { IIndex, Index } from './index'; import { ExtractElementIterable } from './iterables/extract-element-iterable'; import { SkipIterable } from './iterables/skip-iterable'; @@ -80,7 +80,7 @@ export type SelectorWithIndexFn = (value: FromT, index: number) => T //TODO: The Zip function should actually be necessary. Should really just output a series of arrays, collecting each value into one array. // The caller can then run select on it and this means th the zipper function is unecessary. export type ZipNFn = (input: ISeries) => ReturnT; -export type Zip2Fn = (a: T1, b : T2) => ReturnT; +export type Zip2Fn = (a: T1, b: T2) => ReturnT; export type Zip3Fn = (a: T1, b: T2, c: T3) => ReturnT; export type Zip4Fn = (a: T1, b: T2, c: T3, d: T4) => ReturnT; export type Zip5Fn = (a: T1, b: T2, c: T3, d: T4) => ReturnT; @@ -133,7 +133,7 @@ export interface ITypeFrequency { /** * The name of the type. */ - Type: string; + Type: string; /** * The frequency of the type's appearance in the series or dataframe. @@ -149,7 +149,7 @@ export interface IValueFrequency { /** * The value. */ - Value: any; + Value: any; /** * The frequency of the value's appearance in the series or dataframe. @@ -182,7 +182,7 @@ export interface IBucket { * The mid-point value in the bucket. */ Mid: number; - + /** * The maximum value in the bucket. */ @@ -212,11 +212,11 @@ export interface IFrequencyTableOptions { */ upper?: number; - /** - * Directly sets the interval (if defined). This is the range of each group. - */ + /** + * Directly sets the interval (if defined). This is the range of each group. + */ interval?: number; - + /** * Enables capturing of values for each group. */ @@ -286,7 +286,7 @@ export interface ISeries extends Iterable * } * */ - [Symbol.iterator] (): Iterator; + [Symbol.iterator](): Iterator; /** * Cast the value of the series to a new type. @@ -300,7 +300,7 @@ export interface ISeries extends Iterable * const castSeries = series.cast(); * */ - cast (): ISeries; + cast(): ISeries; /** * Get the index for the series. @@ -313,7 +313,7 @@ export interface ISeries extends Iterable * const index = series.getIndex(); * */ - getIndex (): IIndex; + getIndex(): IIndex; /** * Apply a new {@link Index} to the series. @@ -346,7 +346,7 @@ export interface ISeries extends Iterable * const indexedSeries = series.withIndex(value => value + 20); * */ - withIndex (newIndex: Iterable | SelectorFn): ISeries; + withIndex(newIndex: Iterable | SelectorFn): ISeries; /** * Resets the {@link Index} of the series back to the default zero-based sequential integer index. @@ -359,28 +359,28 @@ export interface ISeries extends Iterable * const seriesWithResetIndex = series.resetIndex(); * */ - resetIndex (): ISeries; - - /** - * Merge one or more series into this series. - * Values are merged by index. - * Values at each index are combined into arrays in the resulting series. - * - * @param series... One or more other series to merge into the series. - * - * @returns The merged series. - * - * @example - *
-     * 
-     * const mergedSeries = series1.merge(series2);
-     * 
- * - *
-     * 
-     * const mergedSeries = series1.merge(series2, series3, etc);
-     * 
- */ + resetIndex(): ISeries; + + /** + * Merge one or more series into this series. + * Values are merged by index. + * Values at each index are combined into arrays in the resulting series. + * + * @param series... One or more other series to merge into the series. + * + * @returns The merged series. + * + * @example + *
+      * 
+      * const mergedSeries = series1.merge(series2);
+      * 
+ * + *
+      * 
+      * const mergedSeries = series1.merge(series2, series3, etc);
+      * 
+ */ merge(...args: any[]): ISeries; /** @@ -394,7 +394,7 @@ export interface ISeries extends Iterable * const values = series.toArray(); * */ - toArray (): ValueT[]; + toArray(): ValueT[]; /** * Retreive the index, values pairs from the series as an array. @@ -408,7 +408,7 @@ export interface ISeries extends Iterable * const pairs = series.toPairs(); * */ - toPairs (): ([IndexT,ValueT])[]; + toPairs(): ([IndexT, ValueT])[]; /** * Convert the series to a JavaScript object. @@ -427,7 +427,7 @@ export interface ISeries extends Iterable * ); * */ - toObject (keySelector: (value: ValueT) => KeyT, valueSelector: (value: ValueT) => FieldT): OutT; + toObject(keySelector: (value: ValueT) => KeyT, valueSelector: (value: ValueT) => FieldT): OutT; /** * Transforms an input series, generating a new series. @@ -453,7 +453,7 @@ export interface ISeries extends Iterable * console.log(transformed.toString()); * */ - select (transformer: SelectorWithIndexFn): ISeries; + select(transformer: SelectorWithIndexFn): ISeries; /** * Transforms an input series, generating a new series. @@ -477,8 +477,8 @@ export interface ISeries extends Iterable * console.log(transformed.toString()); * */ - map (transformer: SelectorWithIndexFn): ISeries; - + map(transformer: SelectorWithIndexFn): ISeries; + /** * Transforms and flattens an input series, generating a new series. * The transformer function is called for each value in the input series and produces an array that is then flattened into the generated series. @@ -507,7 +507,7 @@ export interface ISeries extends Iterable * console.log(transformed.toString()); * */ - selectMany (transformer: SelectorWithIndexFn>): ISeries; + selectMany(transformer: SelectorWithIndexFn>): ISeries; /** * Transforms and flattens an input series, generating a new series. @@ -535,8 +535,8 @@ export interface ISeries extends Iterable * console.log(transformed.toString()); * */ - flatMap (transformer: SelectorWithIndexFn>): ISeries; - + flatMap(transformer: SelectorWithIndexFn>): ISeries; + /** * Partition a series into a {@link Series} of *data windows*. * Each value in the new series is a chunk of data from the original series. @@ -562,7 +562,7 @@ export interface ISeries extends Iterable * console.log(weeklySales.toString()); * */ - window (period: number, whichIndex?: WhichIndex): ISeries>; + window(period: number, whichIndex?: WhichIndex): ISeries>; /** * Partition a series into a new series of *rolling data windows*. @@ -581,7 +581,7 @@ export interface ISeries extends Iterable * console.log(rollingWeeklySales.toString()); * */ - rollingWindow (period: number, whichIndex?: WhichIndex): ISeries>; + rollingWindow(period: number, whichIndex?: WhichIndex): ISeries>; /** * Partition a series into a new series of variable-length *data windows* @@ -606,7 +606,7 @@ export interface ISeries extends Iterable * * const variableWindows = series.variableWindow(rowComparer); */ - variableWindow (comparer: ComparerFn): ISeries>; + variableWindow(comparer: ComparerFn): ISeries>; /** * Eliminates adjacent duplicate values. @@ -627,8 +627,8 @@ export interface ISeries extends Iterable * const seriesWithDuplicateRowsRemoved = series.sequentialDistinct(value => value.someNestedField); * */ - sequentialDistinct (selector: SelectorFn): ISeries; - + sequentialDistinct(selector: SelectorFn): ISeries; + /** * Reduces the values in the series to a single result. * @@ -671,8 +671,8 @@ export interface ISeries extends Iterable * }); * */ - aggregate (seedOrSelector: AggregateFn | ToT, selector?: AggregateFn): ToT; - + aggregate(seedOrSelector: AggregateFn | ToT, selector?: AggregateFn): ToT; + /** * Reduces the values in the series to a single result. * @@ -704,7 +704,7 @@ export interface ISeries extends Iterable * ); * */ - reduce (reducer: AggregateFn, seed?: ToT): ToT; + reduce(reducer: AggregateFn, seed?: ToT): ToT; /** * Compute the absolute range of values in each period. @@ -722,7 +722,7 @@ export interface ISeries extends Iterable * const volatility = closingPrice.amountRange(5); * */ - amountRange (period: number, whichIndex?: WhichIndex): ISeries; + amountRange(period: number, whichIndex?: WhichIndex): ISeries; /** * Compute the range of values in each period in proportion to the latest value. @@ -743,7 +743,7 @@ export interface ISeries extends Iterable * const proportionVolatility = closingPrice.proportionRange(5); * */ - proportionRange (period: number, whichIndex?: WhichIndex): ISeries; + proportionRange(period: number, whichIndex?: WhichIndex): ISeries; /** * Compute the range of values in each period in proportion to the latest value. @@ -764,7 +764,7 @@ export interface ISeries extends Iterable * const percentVolatility = closingPrice.percentRange(5); * */ - percentRange (period: number, whichIndex?: WhichIndex): ISeries; + percentRange(period: number, whichIndex?: WhichIndex): ISeries; /** * Compute the amount of change between pairs or sets of values in the series. @@ -787,7 +787,7 @@ export interface ISeries extends Iterable * const amountChanged = salesFigures.amountChanged(7); // Amount that sales has changed, week to week. * */ - amountChange (period?: number, whichIndex?: WhichIndex): ISeries; + amountChange(period?: number, whichIndex?: WhichIndex): ISeries; /** * Compute the proportion change between pairs or sets of values in the series. @@ -811,7 +811,7 @@ export interface ISeries extends Iterable * const proportionChanged = salesFigures.amountChanged(7); // Proportion that sales has changed, week to week. * */ - proportionChange (period?: number, whichIndex?: WhichIndex): ISeries; + proportionChange(period?: number, whichIndex?: WhichIndex): ISeries; /** * Compute the percentage change between pairs or sets of values in the series. @@ -835,7 +835,7 @@ export interface ISeries extends Iterable * const percentChanged = salesFigures.amountChanged(7); // Percent that sales has changed, week to week. * */ - percentChange (period?: number, whichIndex?: WhichIndex): ISeries; + percentChange(period?: number, whichIndex?: WhichIndex): ISeries; /** * For each period, compute the proportion of values that are less than the last value in the period. @@ -856,7 +856,7 @@ export interface ISeries extends Iterable * const proportionRank = series.proportionRank(100); * */ - proportionRank (period?: number): ISeries; + proportionRank(period?: number): ISeries; /** * For each period, compute the percent of values that are less than the last value in the period. @@ -877,15 +877,15 @@ export interface ISeries extends Iterable * const percentRank = series.percentRank(100); * */ - percentRank (period?: number): ISeries; + percentRank(period?: number): ISeries; /** * Generates a cumulative sum across a series. * * @returns Returns a new series that is the cumulative sum of values across the input series. */ - cumsum (): ISeries; - + cumsum(): ISeries; + /** * Skip a number of values in the series. * @@ -899,7 +899,7 @@ export interface ISeries extends Iterable * const seriesWithRowsSkipped = series.skip(10); // Skip 10 rows in the original series. * */ - skip (numValues: number): ISeries; + skip(numValues: number): ISeries; /** * Skips values in the series while a condition evaluates to true or truthy. @@ -914,7 +914,7 @@ export interface ISeries extends Iterable * const seriesWithRowsSkipped = series.skipWhile(salesFigure => salesFigure > 100); // Skip initial sales figure that are less than 100. * */ - skipWhile (predicate: PredicateFn): ISeries; + skipWhile(predicate: PredicateFn): ISeries; /** * Skips values in the series untils a condition evaluates to true or truthy. @@ -929,8 +929,8 @@ export interface ISeries extends Iterable * const seriesWithRowsSkipped = series.skipUntil(salesFigure => salesFigure > 100); // Skip initial sales figures unitl we see one greater than 100. * */ - skipUntil (predicate: PredicateFn): ISeries; - + skipUntil(predicate: PredicateFn): ISeries; + /** * Take a number of values from the series. * @@ -944,8 +944,8 @@ export interface ISeries extends Iterable * const seriesWithRowsTaken = series.take(15); // Take only the first 15 values from the original series. * */ - take (numRows: number): ISeries; - + take(numRows: number): ISeries; + /** * Takes values from the series while a condition evaluates to true or truthy. * @@ -959,7 +959,7 @@ export interface ISeries extends Iterable * const seriesWithRowsTaken = series.takeWhile(salesFigure => salesFigure > 100); // Take only initial sales figures that are greater than 100. * */ - takeWhile (predicate: PredicateFn): ISeries; + takeWhile(predicate: PredicateFn): ISeries; /** * Takes values from the series until a condition evaluates to true or truthy. @@ -974,8 +974,8 @@ export interface ISeries extends Iterable * const seriesWithRowsTaken = series.takeUntil(salesFigure => salesFigure > 100); // Take all initial sales figures until we see one that is greater than 100. * */ - takeUntil (predicate: PredicateFn): ISeries; - + takeUntil(predicate: PredicateFn): ISeries; + /** * Count the number of values in the seriese * @@ -987,8 +987,8 @@ export interface ISeries extends Iterable * const numValues = series.count(); * */ - count (): number; - + count(): number; + /** * Get the first value of the series. * @@ -1000,7 +1000,7 @@ export interface ISeries extends Iterable * const firstValue = series.first(); * */ - first (): ValueT; + first(): ValueT; /** * Get the last value of the series. @@ -1013,7 +1013,7 @@ export interface ISeries extends Iterable * const lastValue = series.last(); * */ - last (): ValueT; + last(): ValueT; /** * Get the value, if there is one, with the specified index. @@ -1036,7 +1036,7 @@ export interface ISeries extends Iterable * const value = series.at(date); * */ - at (index: IndexT): ValueT | undefined; + at(index: IndexT): ValueT | undefined; /** * Get X value from the start of the series. @@ -1052,7 +1052,7 @@ export interface ISeries extends Iterable * const sample = series.head(10); // Take a sample of 10 values from the start of the series. * */ - head (numValues: number): ISeries; + head(numValues: number): ISeries; /** * Get X values from the end of the series. @@ -1068,7 +1068,7 @@ export interface ISeries extends Iterable * const sample = series.tail(12); // Take a sample of 12 values from the end of the series. * */ - tail (numValues: number): ISeries; + tail(numValues: number): ISeries; /** * Filter the series using user-defined predicate function. @@ -1089,7 +1089,7 @@ export interface ISeries extends Iterable * console.log(filtered.toArray()); * */ - where (predicate: PredicateFn): ISeries; + where(predicate: PredicateFn): ISeries; /** * Filter the series through a user-defined predicate function. @@ -1108,7 +1108,7 @@ export interface ISeries extends Iterable * console.log(filtered.toArray()); * */ - filter (predicate: PredicateFn): ISeries; + filter(predicate: PredicateFn): ISeries; /** * Invoke a callback function for each value in the series. @@ -1125,7 +1125,7 @@ export interface ISeries extends Iterable * }); * */ - forEach (callback: CallbackFn): ISeries; + forEach(callback: CallbackFn): ISeries; /** * Evaluates a predicate function for every value in the series to determine @@ -1141,8 +1141,8 @@ export interface ISeries extends Iterable * const result = series.all(salesFigure => salesFigure > 100); // Returns true if all sales figures are greater than 100. * */ - all (predicate: PredicateFn): boolean; - + all(predicate: PredicateFn): boolean; + /** * Evaluates a predicate function for every value in the series to determine * if some condition is true/truthy for **any** of values in the series. @@ -1167,7 +1167,7 @@ export interface ISeries extends Iterable * const result = series.any(); // Do we have any sales figures at all? * */ - any (predicate?: PredicateFn): boolean; + any(predicate?: PredicateFn): boolean; /** * Evaluates a predicate function for every value in the series to determine @@ -1191,7 +1191,7 @@ export interface ISeries extends Iterable * const result = series.none(); // Do we have zero sales figures? * */ - none (predicate?: PredicateFn): boolean; + none(predicate?: PredicateFn): boolean; /** * Gets a new series containing all values starting at or after the specified index value. @@ -1221,7 +1221,7 @@ export interface ISeries extends Iterable * const result = timeSeries.startAt(new Date(2016, 5, 4)); * */ - startAt (indexValue: IndexT): ISeries; + startAt(indexValue: IndexT): ISeries; /** * Gets a new series containing all values up until and including the specified index value (inclusive). @@ -1251,7 +1251,7 @@ export interface ISeries extends Iterable * const result = timeSeries.endAt(new Date(2016, 5, 4)); * */ - endAt (indexValue: IndexT): ISeries; + endAt(indexValue: IndexT): ISeries; /** * Gets a new series containing all values up to the specified index value (exclusive). @@ -1281,7 +1281,7 @@ export interface ISeries extends Iterable * const result = timeSeries.before(new Date(2016, 5, 4)); * */ - before (indexValue: IndexT): ISeries; + before(indexValue: IndexT): ISeries; /** * Gets a new series containing all values after the specified index value (exclusive). @@ -1310,8 +1310,8 @@ export interface ISeries extends Iterable * // Get all values after the specified date. * const result = timeSeries.after(new Date(2016, 5, 4)); * - */ - after (indexValue: IndexT): ISeries; + */ + after(indexValue: IndexT): ISeries; /** * Gets a new series containing all values between the specified index values (inclusive). @@ -1342,7 +1342,7 @@ export interface ISeries extends Iterable * const result = timeSeries.after(new Date(2016, 5, 4), new Date(2016, 5, 22)); * */ - between (startIndexValue: IndexT, endIndexValue: IndexT): ISeries; + between(startIndexValue: IndexT, endIndexValue: IndexT): ISeries; /** * Format the series for display as a string. @@ -1356,7 +1356,7 @@ export interface ISeries extends Iterable * console.log(series.toString()); * */ - toString (): string; + toString(): string; /** * Parse a series with string values and convert it to a series with int values. @@ -1369,7 +1369,7 @@ export interface ISeries extends Iterable * const parsed = series.parseInts(); * */ - parseInts (): ISeries; + parseInts(): ISeries; /** * Parse a series with string values and convert it to a series with float values. @@ -1382,7 +1382,7 @@ export interface ISeries extends Iterable * const parsed = series.parseFloats(); * */ - parseFloats (): ISeries; + parseFloats(): ISeries; /** * Parse a series with string values and convert it to a series with date values. @@ -1400,7 +1400,7 @@ export interface ISeries extends Iterable * const parsed = series.parseDates(); * */ - parseDates (formatString?: string): ISeries; + parseDates(formatString?: string): ISeries; /** * Convert a series of values of different types to a series containing string values. @@ -1427,7 +1427,7 @@ export interface ISeries extends Iterable * const result = series.toStrings("0.00"); * */ - toStrings (formatString?: string): ISeries; + toStrings(formatString?: string): ISeries; /** * Forces lazy evaluation to complete and 'bakes' the series into memory. @@ -1440,7 +1440,7 @@ export interface ISeries extends Iterable * const baked = series.bake(); * */ - bake (): ISeries; + bake(): ISeries; /** * Converts (inflates) a series to a {@link DataFrame}. @@ -1467,7 +1467,7 @@ export interface ISeries extends Iterable * const dataframe = series.inflate(value => { AColumn: value.NestedValue }); // Extract a nested value and produce a dataframe from it. * */ - inflate (selector?: SelectorWithIndexFn): IDataFrame; + inflate(selector?: SelectorWithIndexFn): IDataFrame; /** * Sum the values in a series and returns the result. @@ -1480,7 +1480,7 @@ export interface ISeries extends Iterable * const totalSales = salesFigures.sum(); * */ - sum (): number; + sum(): number; /** * Average the values in a series and returns the result. @@ -1495,7 +1495,7 @@ export interface ISeries extends Iterable * const averageSales = salesFigures.average(); * */ - average (): number; + average(): number; /** * Computes and returns the mean value of a set of values. @@ -1508,7 +1508,7 @@ export interface ISeries extends Iterable * const averageSales = salesFigures.mean(); * */ - mean (): number; + mean(): number; /** * Get the median value in the series. @@ -1522,8 +1522,8 @@ export interface ISeries extends Iterable * const medianSales = salesFigures.median(); * */ - median (): number; - + median(): number; + /** * Get the mode of the values in the series. * The mode is the most frequent value in the series. @@ -1537,7 +1537,7 @@ export interface ISeries extends Iterable * const modeSales = salesFigures.mode(); * */ - mode (): any; + mode(): any; /** * Get the variance of number values in the series. @@ -1550,7 +1550,7 @@ export interface ISeries extends Iterable * const salesVariance = salesFigures.variance(); * */ - variance (): number; + variance(): number; /** * Get the standard deviation of number values in the series. @@ -1563,7 +1563,7 @@ export interface ISeries extends Iterable * const salesStdDev = salesFigures.std(); * */ - std (): number; + std(): number; /** * Standardize a series of numbers by converting each "standard deviations from the mean". @@ -1577,7 +1577,7 @@ export interface ISeries extends Iterable * const standardizedSeries = series.standardize(); * */ - standardize (): ISeries; + standardize(): ISeries; /** * Get the (sample) variance of number values in the series. @@ -1590,7 +1590,7 @@ export interface ISeries extends Iterable * const salesVariance = salesFigures.variance(); * */ - sampleVariance (): number; + sampleVariance(): number; /** * Get the (sample) standard deviation of number values in the series. @@ -1603,7 +1603,7 @@ export interface ISeries extends Iterable * const salesStdDev = salesFigures.sampleStd(); * */ - sampleStd (): number; + sampleStd(): number; /** * Standardize a series of numbers by converting each "standard deviations from the mean". @@ -1617,7 +1617,7 @@ export interface ISeries extends Iterable * const standardizedSeries = series.sampleStandardize(); * */ - sampleStandardize (): ISeries; + sampleStandardize(): ISeries; /** * Get the min value in the series. @@ -1630,7 +1630,7 @@ export interface ISeries extends Iterable * const minSales = salesFigures.min(); * */ - min (): number; + min(): number; /** * Get the max value in the series. @@ -1643,7 +1643,7 @@ export interface ISeries extends Iterable * const maxSales = salesFigures.max(); * */ - max (): number; + max(): number; /** * Get the range of values in the series. @@ -1656,7 +1656,7 @@ export interface ISeries extends Iterable * const range = salesFigures.range(); * */ - range (): number; + range(): number; /** * Invert the sign of every number value in the series. @@ -1670,7 +1670,7 @@ export interface ISeries extends Iterable * const inverted = series.invert(); * */ - invert (): ISeries; + invert(): ISeries; /** * Counts the number of sequential values where the predicate evaluates to truthy. @@ -1688,7 +1688,7 @@ export interface ISeries extends Iterable * console.log(counted.toString()); * */ - counter (predicate: PredicateFn): ISeries; + counter(predicate: PredicateFn): ISeries; /** * Gets a new series in reverse order. @@ -1701,7 +1701,7 @@ export interface ISeries extends Iterable * const reversed = series.reverse(); * */ - reverse (): ISeries; + reverse(): ISeries; /** * Returns only the set of values in the series that are distinct. @@ -1724,7 +1724,7 @@ export interface ISeries extends Iterable * const bucketedValues = series.distinct(value => Math.floor(value / 10)); // Lump values into buckets of 10. * */ - distinct (selector?: SelectorFn): ISeries; + distinct(selector?: SelectorFn): ISeries; /** * Collects values in the series into a new series of groups according to a user-defined selector function. @@ -1746,7 +1746,7 @@ export interface ISeries extends Iterable * } * */ - groupBy (selector: SelectorFn): ISeries>; + groupBy(selector: SelectorFn): ISeries>; /** * Collects values in the series into a new series of groups based on if the values are the same or according to a user-defined selector function. @@ -1775,9 +1775,9 @@ export interface ISeries extends Iterable * } * } * - */ - groupSequentialBy (selector?: SelectorFn): ISeries>; - + */ + groupSequentialBy(selector?: SelectorFn): ISeries>; + /** * Concatenate multiple other series onto this series. * @@ -1815,8 +1815,8 @@ export interface ISeries extends Iterable * const otherSeries = [... array of series...]; * const concatenated = a.concat(otherSeries); * - */ - concat (...series: (ISeries[]|ISeries)[]): ISeries; + */ + concat(...series: (ISeries[] | ISeries)[]): ISeries; /** * Zip together multiple series to create a new series. @@ -1834,12 +1834,12 @@ export interface ISeries extends Iterable * const b = new Series([10, 20, 30]); * const zipped = a.zip(b (valueA, valueB) => valueA + valueB); * - */ - zip (s2: ISeries, zipper: Zip2Fn ): ISeries; - zip (s2: ISeries, s3: ISeries, zipper: Zip3Fn ): ISeries; - zip (s2: ISeries, s3: ISeries, s4: ISeries, zipper: Zip3Fn ): ISeries; - zip (...args: any[]): ISeries; - + */ + zip(s2: ISeries, zipper: Zip2Fn): ISeries; + zip(s2: ISeries, s3: ISeries, zipper: Zip3Fn): ISeries; + zip(s2: ISeries, s3: ISeries, s4: ISeries, zipper: Zip3Fn): ISeries; + zip(...args: any[]): ISeries; + /** * Sorts the series in ascending order by a value defined by the user-defined selector function. * @@ -1859,7 +1859,7 @@ export interface ISeries extends Iterable * const orderedSeries = series.orderBy(value => value.NestedValue); * */ - orderBy (selector: SelectorWithIndexFn): IOrderedSeries; + orderBy(selector: SelectorWithIndexFn): IOrderedSeries; /** * Sorts the series in descending order by a value defined by the user-defined selector function. @@ -1880,7 +1880,7 @@ export interface ISeries extends Iterable * const orderedSeries = series.orderByDescending(value => value.NestedValue); * */ - orderByDescending (selector: SelectorWithIndexFn): IOrderedSeries; + orderByDescending(selector: SelectorWithIndexFn): IOrderedSeries; /** * Creates a new series by merging two input dataframes. @@ -1932,10 +1932,10 @@ export interface ISeries extends Iterable * * */ - union ( - other: ISeries, - selector?: SelectorFn): - ISeries; + union( + other: ISeries, + selector?: SelectorFn): + ISeries; /** * Creates a new series by merging two input series. @@ -1968,12 +1968,12 @@ export interface ISeries extends Iterable * customerRecord => customerRecord.CustomerId * ); * - */ - intersection ( - inner: ISeries, + */ + intersection( + inner: ISeries, outerSelector?: SelectorFn, - innerSelector?: SelectorFn): - ISeries; + innerSelector?: SelectorFn): + ISeries; /** * Creates a new series by merging two input series. @@ -2005,49 +2005,49 @@ export interface ISeries extends Iterable * customerRecord => customerRecord.CustomerId * ); * - */ - except ( - inner: ISeries, - outerSelector?: SelectorFn, - innerSelector?: SelectorFn): - ISeries; - - /** - * Creates a new series by merging two input series. - * The resulting dataframe contains only those value that have matching keys in both input series. - * - * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series). - * @param outerKeySelector User-defined selector function that chooses the join key from the outer series. - * @param innerKeySelector User-defined selector function that chooses the join key from the inner series. - * @param resultSelector User-defined function that merges outer and inner values. - * - * @return Returns the new merged series. - * - * @example - *
-     * 
-     * // Join together two sets of customers to find those
-     * // that have bought both product A and product B.
-     * const customerWhoBoughtProductA = ...
-     * const customerWhoBoughtProductB = ...
-     * const customersWhoBoughtBothProductsDf = customerWhoBoughtProductA.join(
-     *          customerWhoBoughtProductB,
-     *          customerA => customerA.CustomerId, // Join key.
-     *          customerB => customerB.CustomerId, // Join key.
-     *          (customerA, customerB) => {
-     *              return {
-     *                  // ... merge the results ...
-     *              };
-     *          }
-     *      );
-     * 
*/ - join ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + except( + inner: ISeries, + outerSelector?: SelectorFn, + innerSelector?: SelectorFn): + ISeries; + + /** + * Creates a new series by merging two input series. + * The resulting dataframe contains only those value that have matching keys in both input series. + * + * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series). + * @param outerKeySelector User-defined selector function that chooses the join key from the outer series. + * @param innerKeySelector User-defined selector function that chooses the join key from the inner series. + * @param resultSelector User-defined function that merges outer and inner values. + * + * @return Returns the new merged series. + * + * @example + *
+      * 
+      * // Join together two sets of customers to find those
+      * // that have bought both product A and product B.
+      * const customerWhoBoughtProductA = ...
+      * const customerWhoBoughtProductB = ...
+      * const customersWhoBoughtBothProductsDf = customerWhoBoughtProductA.join(
+      *          customerWhoBoughtProductB,
+      *          customerA => customerA.CustomerId, // Join key.
+      *          customerB => customerB.CustomerId, // Join key.
+      *          (customerA, customerB) => {
+      *              return {
+      *                  // ... merge the results ...
+      *              };
+      *          }
+      *      );
+      * 
+ */ + join( + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries; + ISeries; /** * Creates a new series by merging two input series. @@ -2082,13 +2082,13 @@ export interface ISeries extends Iterable * } * ); * - */ - joinOuter ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + */ + joinOuter( + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries; + ISeries; /** * Creates a new series by merging two input series. @@ -2124,12 +2124,12 @@ export interface ISeries extends Iterable * ); * */ - joinOuterLeft ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + joinOuterLeft( + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries; + ISeries; /** * Creates a new series by merging two input series. @@ -2165,12 +2165,12 @@ export interface ISeries extends Iterable * ); * */ - joinOuterRight ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + joinOuterRight( + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries; + ISeries; /** * Produces a new series with all string values truncated to the requested maximum length. @@ -2185,7 +2185,7 @@ export interface ISeries extends Iterable * const truncated = series.truncateStrings(10); // Truncate all string values to max length of 10 characters. * */ - truncateStrings (maxLength: number): ISeries; + truncateStrings(maxLength: number): ISeries; /** * Produces a new series with all number values rounded to the specified number of places. @@ -2208,7 +2208,7 @@ export interface ISeries extends Iterable * const rounded = series.round(3); // Round numbers to three decimal places. * */ - round (numDecimalPlaces?: number): ISeries; + round(numDecimalPlaces?: number): ISeries; /** * Insert a pair at the start of the series. @@ -2226,7 +2226,7 @@ export interface ISeries extends Iterable * const insertedSeries = series.insertPair([newIndex, newRows]); * */ - insertPair (pair: [IndexT, ValueT]): ISeries; + insertPair(pair: [IndexT, ValueT]): ISeries; /** * Append a pair to the end of a series. @@ -2244,13 +2244,13 @@ export interface ISeries extends Iterable * const appendedSeries = series.appendPair([newIndex, newRows]); * */ - appendPair (pair: [IndexT, ValueT]): ISeries; + appendPair(pair: [IndexT, ValueT]): ISeries; /** * Removes values from the series by index. */ remove(index: IndexT): ISeries; - + /** * Fill gaps in a series. * @@ -2283,7 +2283,7 @@ export interface ISeries extends Iterable * var sequenceWithoutGaps = sequenceWithGaps.fillGaps(gapExists, gapFiller); * */ - fillGaps (comparer: ComparerFn<[IndexT, ValueT], [IndexT, ValueT]>, generator: GapFillFn<[IndexT, ValueT], [IndexT, ValueT]>): ISeries; + fillGaps(comparer: ComparerFn<[IndexT, ValueT], [IndexT, ValueT]>, generator: GapFillFn<[IndexT, ValueT], [IndexT, ValueT]>): ISeries; /** * Returns the specified default series if the input series is empty. @@ -2308,7 +2308,7 @@ export interface ISeries extends Iterable * expect(nonEmptySeries.defaultIfEmpty(defaultSeries)).to.eql(nonEmptySeries); * */ - defaultIfEmpty (defaultSequence: ValueT[] | ISeries): ISeries; + defaultIfEmpty(defaultSequence: ValueT[] | ISeries): ISeries; /** * Detect the the frequency of the types of the values in the series. @@ -2323,7 +2323,7 @@ export interface ISeries extends Iterable * console.log(dataTypes.toString()); * */ - detectTypes (): IDataFrame; + detectTypes(): IDataFrame; /** * Detect the frequency of the values in the series. @@ -2338,7 +2338,7 @@ export interface ISeries extends Iterable * console.log(dataValues.toString()); * */ - detectValues (): IDataFrame; + detectValues(): IDataFrame; /** * Organise all values in the series into the specified number of buckets. @@ -2357,7 +2357,7 @@ export interface ISeries extends Iterable * console.log(buckets.toString()); * */ - bucket (numBuckets: number): IDataFrame; + bucket(numBuckets: number): IDataFrame; /** * Counts frequencies in the series to produce a frequency table. @@ -2388,7 +2388,7 @@ export interface ISeries extends Iterable * console.log(frequencyTable.toArray()); * */ - frequency (options?: IFrequencyTableOptions): IDataFrame; + frequency(options?: IFrequencyTableOptions): IDataFrame; } /** @@ -2410,7 +2410,7 @@ export interface IOrderedSeries exte * const ordered = sales.orderBy(sale => sale.SalesPerson).thenBy(sale => sale.Amount); * */ - thenBy (selector: SelectorWithIndexFn): IOrderedSeries; + thenBy(selector: SelectorWithIndexFn): IOrderedSeries; /** * Applys additional sorting (descending) to an already sorted series. @@ -2426,7 +2426,7 @@ export interface IOrderedSeries exte * const ordered = sales.orderBy(sale => sale.SalesPerson).thenByDescending(sale => sale.Amount); * */ - thenByDescending (selector: SelectorWithIndexFn): IOrderedSeries; + thenByDescending(selector: SelectorWithIndexFn): IOrderedSeries; } // @@ -2453,7 +2453,7 @@ interface ISeriesContent { * Set to true when the dataframe has been baked into memory * and does not need to be lazily evaluated. */ - isBaked: boolean; + isBaked: boolean; } /** @@ -2522,8 +2522,8 @@ export class Series implements ISeries implements ISeries { + private getContent(): ISeriesContent { this.lazyInit(); return this.content!; } @@ -2705,7 +2705,7 @@ export class Series implements ISeries implements ISeries(); * */ - cast (): ISeries { + cast(): ISeries { return this as any as ISeries; } - + /** * Get the index for the series. * @@ -2755,7 +2755,7 @@ export class Series implements ISeries */ - getIndex (): IIndex { + getIndex(): IIndex { return new Index(() => ({ values: this.getContent().index })); } @@ -2790,7 +2790,7 @@ export class Series implements ISeries value + 20); * */ - withIndex (newIndex: Iterable | SelectorFn): ISeries { + withIndex(newIndex: Iterable | SelectorFn): ISeries { if (isFunction(newIndex)) { return new Series(() => ({ @@ -2800,7 +2800,7 @@ export class Series implements ISeries, 'newIndex'); - + return new Series(() => ({ values: this.getContent().values, index: newIndex as Iterable, @@ -2819,7 +2819,7 @@ export class Series implements ISeries */ - resetIndex (): ISeries { + resetIndex(): ISeries { return new Series(() => ({ values: this.getContent().values // Just strip the index. })); @@ -2842,7 +2842,7 @@ export class Series implements ISeries(series: Iterable>): ISeries { - const rowMap = new Map(); + const rowMap = new Map(); const numSeries = Array.from(series).length; //TODO: Be nice not to have to do this. let seriesIndex = 0; for (const workingSeries of series) { @@ -2878,30 +2878,30 @@ export class Series implements ISeries - * - * const mergedSeries = series1.merge(series2); - * - * - *
-     * 
-     * const mergedSeries = series1.merge(series2, series3, etc);
-     * 
- */ + /** + * Merge one or more series into this series. + * Values are merged by index. + * Values at each index are combined into arrays in the resulting series. + * + * @param series... One or more other series to merge into the series. + * + * @returns The merged series. + * + * @example + *
+      * 
+      * const mergedSeries = series1.merge(series2);
+      * 
+ * + *
+      * 
+      * const mergedSeries = series1.merge(series2, series3, etc);
+      * 
+ */ merge(...args: any[]): ISeries { return Series.merge([this].concat(args)); } - + /** * Extract values from the series as an array. * This forces lazy evaluation to complete. @@ -2913,10 +2913,12 @@ export class Series implements ISeries */ - toArray (): any[] { + toArray(options?: { includeNulls?: boolean }): any[] { const values = []; for (const value of this.getContent().values) { - if (value !== undefined && value !== null) { + if (options && options.includeNulls && value !== undefined) { + values.push(value); + } else if (value !== undefined && value !== null) { values.push(value); } } @@ -2935,7 +2937,7 @@ export class Series implements ISeries */ - toPairs (): ([IndexT, ValueT])[] { + toPairs(): ([IndexT, ValueT])[] { const pairs = []; for (const pair of this.getContent().pairs) { if (pair[1] !== undefined && pair[1] !== null) { @@ -2962,14 +2964,14 @@ export class Series implements ISeries */ - toObject (keySelector: (value: ValueT) => KeyT, valueSelector: (value: ValueT) => FieldT): OutT { + toObject(keySelector: (value: ValueT) => KeyT, valueSelector: (value: ValueT) => FieldT): OutT { if (!isFunction(keySelector)) throw new Error("Expected 'keySelector' parameter to Series.toObject to be a function."); if (!isFunction(valueSelector)) throw new Error("Expected 'valueSelector' parameter to Series.toObject to be a function."); return toMap(this, keySelector, valueSelector); } - + /** * Transforms an input series, generating a new series. * The transformer function is called for each element of the input and the collection of outputs creates the generated series. @@ -2994,7 +2996,7 @@ export class Series implements ISeries */ - select (transformer: SelectorWithIndexFn): ISeries { + select(transformer: SelectorWithIndexFn): ISeries { if (!isFunction(transformer)) throw new Error("Expected 'transformer' parameter to 'Series.select' to be a function."); return this.map(transformer); @@ -3022,7 +3024,7 @@ export class Series implements ISeries */ - map (transformer: SelectorWithIndexFn): ISeries { + map(transformer: SelectorWithIndexFn): ISeries { if (!isFunction(transformer)) throw new Error("Expected 'transformer' parameter to 'Series.map' to be a function."); return new Series(() => { @@ -3062,7 +3064,7 @@ export class Series implements ISeries */ - selectMany (transformer: SelectorWithIndexFn>): ISeries { + selectMany(transformer: SelectorWithIndexFn>): ISeries { if (!isFunction(transformer)) throw new Error("Expected 'transformer' parameter to 'Series.selectMany' to be a function."); return this.flatMap(transformer); @@ -3094,12 +3096,12 @@ export class Series implements ISeries */ - flatMap (transformer: SelectorWithIndexFn>): ISeries { + flatMap(transformer: SelectorWithIndexFn>): ISeries { if (!isFunction(transformer)) throw new Error("Expected 'transformer' parameter to 'Series.flatMap' to be a function."); return new Series(() => ({ pairs: new SelectManyIterable( - this.getContent().pairs, + this.getContent().pairs, (pair: [IndexT, ValueT], index: number): Iterable<[IndexT, ToT]> => { const outputPairs: [IndexT, ToT][] = []; for (const transformed of transformer(pair[1], index)) { @@ -3139,7 +3141,7 @@ export class Series implements ISeries */ - window (period: number, whichIndex?: WhichIndex): ISeries> { + window(period: number, whichIndex?: WhichIndex): ISeries> { if (!isNumber(period)) throw new Error("Expected 'period' parameter to 'Series.window' to be a number."); @@ -3165,7 +3167,7 @@ export class Series implements ISeries */ - rollingWindow (period: number, whichIndex?: WhichIndex): ISeries> { + rollingWindow(period: number, whichIndex?: WhichIndex): ISeries> { if (!isNumber(period)) throw new Error("Expected 'period' parameter to 'Series.rollingWindow' to be a number."); @@ -3197,8 +3199,8 @@ export class Series implements ISeries): ISeries> { - + variableWindow(comparer: ComparerFn): ISeries> { + if (!isFunction(comparer)) throw new Error("Expected 'comparer' parameter to 'Series.variableWindow' to be a function.") return new Series>(() => ({ @@ -3225,18 +3227,18 @@ export class Series implements ISeries value.someNestedField); * */ - sequentialDistinct (selector?: SelectorFn): ISeries { - + sequentialDistinct(selector?: SelectorFn): ISeries { + if (selector) { if (!isFunction(selector)) throw new Error("Expected 'selector' parameter to 'Series.sequentialDistinct' to be a selector function that determines the value to compare for duplicates.") } else { - selector = (value: ValueT): ToT => value; + selector = (value: ValueT): ToT => value; } return this.variableWindow((a, b) => selector!(a) === selector!(b)) .select((window): [IndexT, ValueT] => { - return [window.getIndex().first(), window.first()] ; + return [window.getIndex().first(), window.first()]; }) .withIndex(pair => pair[0]) .select(pair => pair[1]); @@ -3284,15 +3286,15 @@ export class Series implements ISeries */ - aggregate (seedOrSelector: AggregateFn | ToT, selector?: AggregateFn): ToT { + aggregate(seedOrSelector: AggregateFn | ToT, selector?: AggregateFn): ToT { if (isFunction(seedOrSelector) && !selector) { - return this.skip(1).aggregate( this.first(), seedOrSelector); + return this.skip(1).aggregate(this.first(), seedOrSelector); } else { if (!isFunction(selector)) throw new Error("Expected 'selector' parameter to aggregate to be a function."); - let accum = seedOrSelector; + let accum = seedOrSelector; for (const value of this) { accum = selector!(accum, value); @@ -3301,7 +3303,7 @@ export class Series implements ISeries implements ISeries */ - reduce (reducer: AggregateFn, seed?: ToT): ToT { + reduce(reducer: AggregateFn, seed?: ToT): ToT { if (!isFunction(reducer)) throw new Error("Expected 'reducer' parameter to `Series.reduce` to be a function."); - let accum = seed; + let accum = seed; let series: ISeries = this; if (accum === undefined) { if (series.any()) { @@ -3367,11 +3369,11 @@ export class Series implements ISeries */ - amountRange (period: number, whichIndex?: WhichIndex): ISeries { - return (> this) // Have to assume this is a number series. + amountRange(period: number, whichIndex?: WhichIndex): ISeries { + return (>this) // Have to assume this is a number series. .rollingWindow(period, whichIndex) .select(window => window.max() - window.min()); - } + } /** * Compute the range of values in each period in proportion to the latest value. @@ -3391,11 +3393,11 @@ export class Series implements ISeries */ - proportionRange (period: number, whichIndex?: WhichIndex): ISeries { - return (> this) // Have to assume this is a number series. + proportionRange(period: number, whichIndex?: WhichIndex): ISeries { + return (>this) // Have to assume this is a number series. .rollingWindow(period, whichIndex) .select(window => (window.max() - window.min()) / window.last()); - } + } /** * Compute the range of values in each period in proportion to the latest value. @@ -3415,7 +3417,7 @@ export class Series implements ISeries */ - percentRange (period: number, whichIndex?: WhichIndex): ISeries { + percentRange(period: number, whichIndex?: WhichIndex): ISeries { return this.proportionRange(period, whichIndex).select(v => v * 100); } @@ -3439,11 +3441,11 @@ export class Series implements ISeries */ - amountChange (period?: number, whichIndex?: WhichIndex): ISeries { - return (> this) // Have to assume this is a number series. + amountChange(period?: number, whichIndex?: WhichIndex): ISeries { + return (>this) // Have to assume this is a number series. .rollingWindow(period === undefined ? 2 : period, whichIndex) .select(window => window.last() - window.first()); - } + } /** * Compute the proportion change between pairs or sets of values in the series. @@ -3466,11 +3468,11 @@ export class Series implements ISeries */ - proportionChange (period?: number, whichIndex?: WhichIndex): ISeries { - return (> this) // Have to assume this is a number series. + proportionChange(period?: number, whichIndex?: WhichIndex): ISeries { + return (>this) // Have to assume this is a number series. .rollingWindow(period === undefined ? 2 : period, whichIndex) - .select(window => (window.last() - window.first()) / window.first()); - } + .select(window => (window.last() - window.first()) / window.first()); + } /** * Compute the percentage change between pairs or sets of values in the series. @@ -3493,10 +3495,10 @@ export class Series implements ISeries */ - percentChange (period?: number, whichIndex?: WhichIndex): ISeries { + percentChange(period?: number, whichIndex?: WhichIndex): ISeries { return this.proportionChange(period, whichIndex).select(v => v * 100); - } - + } + /** * For each period, compute the proportion of values that are less than the last value in the period. * Proportions are expressed as 0-1 values. @@ -3516,7 +3518,7 @@ export class Series implements ISeries */ - proportionRank (period?: number): ISeries { + proportionRank(period?: number): ISeries { if (period === undefined) { period = 2; } @@ -3524,8 +3526,8 @@ export class Series implements ISeries { const latestValue = window.last(); const numLowerValues = window.head(-1).filter(prevMomentum => prevMomentum < latestValue).count(); @@ -3553,7 +3555,7 @@ export class Series implements ISeries */ - percentRank (period?: number): ISeries { + percentRank(period?: number): ISeries { if (period === undefined) { period = 2; } @@ -3561,7 +3563,7 @@ export class Series implements ISeries proportion * 100); } @@ -3570,7 +3572,7 @@ export class Series implements ISeries { + cumsum(): ISeries { return new Series(() => { let working = 0; const pairs: any[][] = this.toPairs(); @@ -3592,14 +3594,14 @@ export class Series implements ISeries */ - skip (numValues: number): ISeries { + skip(numValues: number): ISeries { return new Series(() => ({ values: new SkipIterable(this.getContent().values, numValues), index: new SkipIterable(this.getContent().index, numValues), pairs: new SkipIterable(this.getContent().pairs, numValues), })); } - + /** * Skips values in the series while a condition evaluates to true or truthy. * @@ -3613,7 +3615,7 @@ export class Series implements ISeries salesFigure > 100); // Skip initial sales figure that are less than 100. * */ - skipWhile (predicate: PredicateFn): ISeries { + skipWhile(predicate: PredicateFn): ISeries { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.skipWhile' function to be a predicate function that returns true/false."); return new Series(() => ({ @@ -3635,10 +3637,10 @@ export class Series implements ISeries salesFigure > 100); // Skip initial sales figures unitl we see one greater than 100. * */ - skipUntil (predicate: PredicateFn): ISeries { + skipUntil(predicate: PredicateFn): ISeries { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.skipUntil' function to be a predicate function that returns true/false."); - return this.skipWhile(value => !predicate(value)); + return this.skipWhile(value => !predicate(value)); } /** @@ -3654,7 +3656,7 @@ export class Series implements ISeries */ - take (numRows: number): ISeries { + take(numRows: number): ISeries { if (!isNumber(numRows)) throw new Error("Expected 'numRows' parameter to 'Series.take' function to be a number."); return new Series(() => ({ @@ -3677,7 +3679,7 @@ export class Series implements ISeries salesFigure > 100); // Take only initial sales figures that are greater than 100. * */ - takeWhile (predicate: PredicateFn): ISeries { + takeWhile(predicate: PredicateFn): ISeries { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.takeWhile' function to be a predicate function that returns true/false."); return new Series(() => ({ @@ -3699,7 +3701,7 @@ export class Series implements ISeries salesFigure > 100); // Take all initial sales figures until we see one that is greater than 100. * */ - takeUntil (predicate: PredicateFn): ISeries { + takeUntil(predicate: PredicateFn): ISeries { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.takeUntil' function to be a predicate function that returns true/false."); return this.takeWhile(value => !predicate(value)); @@ -3720,10 +3722,10 @@ export class Series implements ISeries */ - static count (series: ISeries): number { + static count(series: ISeries): number { return series.count(); } - + /** * Count the number of values in the series. * @@ -3735,7 +3737,7 @@ export class Series implements ISeries */ - count (): number { + count(): number { let total = 0; for (const value of this.getContent().values) { @@ -3755,7 +3757,7 @@ export class Series implements ISeries */ - first (): ValueT { + first(): ValueT { for (const value of this) { return value; // Only need the first value. @@ -3775,7 +3777,7 @@ export class Series implements ISeries */ - last (): ValueT { + last(): ValueT { let lastValue = null; @@ -3788,8 +3790,8 @@ export class Series implements ISeries implements ISeries */ - at (index: IndexT): ValueT | undefined { + at(index: IndexT): ValueT | undefined { if (this.none()) { return undefined; @@ -3819,7 +3821,7 @@ export class Series implements ISeries implements ISeries */ - head (numValues: number): ISeries { + head(numValues: number): ISeries { if (!isNumber(numValues)) throw new Error("Expected 'numValues' parameter to 'Series.head' function to be a number."); @@ -3860,7 +3862,7 @@ export class Series implements ISeries */ - tail (numValues: number): ISeries { + tail(numValues: number): ISeries { if (!isNumber(numValues)) throw new Error("Expected 'numValues' parameter to 'Series.tail' function to be a number."); @@ -3891,7 +3893,7 @@ export class Series implements ISeries */ - where (predicate: PredicateFn): ISeries { + where(predicate: PredicateFn): ISeries { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.where' to be a function."); return this.filter(predicate); @@ -3914,7 +3916,7 @@ export class Series implements ISeries */ - filter (predicate: PredicateFn): ISeries { + filter(predicate: PredicateFn): ISeries { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.filter' to be a function."); return new Series(() => { @@ -3941,7 +3943,7 @@ export class Series implements ISeries */ - forEach (callback: CallbackFn): ISeries { + forEach(callback: CallbackFn): ISeries { if (!isFunction(callback)) throw new Error("Expected 'callback' parameter to 'Series.forEach' to be a function."); let index = 0; @@ -3966,7 +3968,7 @@ export class Series implements ISeries salesFigure > 100); // Returns true if all sales figures are greater than 100. * */ - all (predicate: PredicateFn): boolean { + all(predicate: PredicateFn): boolean { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.all' to be a function.") let count = 0; @@ -4006,7 +4008,7 @@ export class Series implements ISeries */ - any (predicate?: PredicateFn): boolean { + any(predicate?: PredicateFn): boolean { if (predicate) { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.any' to be a function.") } @@ -4050,7 +4052,7 @@ export class Series implements ISeries */ - none (predicate?: PredicateFn): boolean { + none(predicate?: PredicateFn): boolean { if (predicate) { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.none' to be a function.") @@ -4101,10 +4103,10 @@ export class Series implements ISeries */ - startAt (indexValue: IndexT): ISeries { + startAt(indexValue: IndexT): ISeries { return new Series(() => { const lessThan = this.getIndex().getLessThan(); - return { + return { index: new SkipWhileIterable(this.getContent().index, index => lessThan(index, indexValue)), pairs: new SkipWhileIterable(this.getContent().pairs, pair => lessThan(pair[0], indexValue)), } @@ -4139,7 +4141,7 @@ export class Series implements ISeries */ - endAt (indexValue: IndexT): ISeries { + endAt(indexValue: IndexT): ISeries { return new Series(() => { const lessThanOrEqualTo = this.getIndex().getLessThanOrEqualTo(); return { @@ -4177,7 +4179,7 @@ export class Series implements ISeries */ - before (indexValue: IndexT): ISeries { + before(indexValue: IndexT): ISeries { return new Series(() => { const lessThan = this.getIndex().getLessThan(); return { @@ -4214,8 +4216,8 @@ export class Series implements ISeries - */ - after (indexValue: IndexT): ISeries { + */ + after(indexValue: IndexT): ISeries { return new Series(() => { const lessThanOrEqualTo = this.getIndex().getLessThanOrEqualTo(); return { @@ -4254,8 +4256,8 @@ export class Series implements ISeries */ - between (startIndexValue: IndexT, endIndexValue: IndexT): ISeries { - return this.startAt(startIndexValue).endAt(endIndexValue); + between(startIndexValue: IndexT, endIndexValue: IndexT): ISeries { + return this.startAt(startIndexValue).endAt(endIndexValue); } /** @@ -4270,7 +4272,7 @@ export class Series implements ISeries */ - toString (): string { + toString(): string { const header = ["__index__", "__value__"]; const rows = this.toPairs(); @@ -4291,13 +4293,13 @@ export class Series implements ISeries implements ISeries */ - parseInts (): ISeries { - return > this.select(Series.parseInt); + parseInts(): ISeries { + return >this.select(Series.parseInt); } // // Helper function to parse a string to a float. // - static parseFloat (value: any | undefined | null, valueIndex: number): number | undefined { + static parseFloat(value: any | undefined | null, valueIndex: number): number | undefined { if (value === undefined || value === null) { return undefined; } else { - if (!isString(value)) throw new Error("Called Series.parseFloats, expected all values in the series to be strings, instead found a '" + typeof(value) + "' at index " + valueIndex); + if (!isString(value)) throw new Error("Called Series.parseFloats, expected all values in the series to be strings, instead found a '" + typeof (value) + "' at index " + valueIndex); if (value.length === 0) { return undefined; @@ -4352,19 +4354,19 @@ export class Series implements ISeries */ - parseFloats (): ISeries { - return > this.select(Series.parseFloat); + parseFloats(): ISeries { + return >this.select(Series.parseFloat); } // // Helper function to parse a string to a date. // - static parseDate (value: any | undefined | null, valueIndex: number, formatString?: string): Date | undefined { + static parseDate(value: any | undefined | null, valueIndex: number, formatString?: string): Date | undefined { if (value === undefined || value === null) { return undefined; } else { - if (!isString(value)) throw new Error("Called Series.parseDates, expected all values in the series to be strings, instead found a '" + typeof(value) + "' at index " + valueIndex); + if (!isString(value)) throw new Error("Called Series.parseDates, expected all values in the series to be strings, instead found a '" + typeof (value) + "' at index " + valueIndex); if (value.length === 0) { return undefined; @@ -4390,13 +4392,13 @@ export class Series implements ISeries */ - parseDates (formatString?: string): ISeries { + parseDates(formatString?: string): ISeries { if (formatString) { if (!isString(formatString)) throw new Error("Expected optional 'formatString' parameter to Series.parseDates to be a string (if specified)."); } - return > this.select((value: any | undefined, valueIndex: number) => Series.parseDate(value, valueIndex, formatString)); + return >this.select((value: any | undefined, valueIndex: number) => Series.parseDate(value, valueIndex, formatString)); } // @@ -4416,8 +4418,8 @@ export class Series implements ISeries implements ISeries */ - toStrings (formatString?: string): ISeries { + toStrings(formatString?: string): ISeries { if (formatString) { if (!isString(formatString)) throw new Error("Expected optional 'formatString' parameter to Series.toStrings to be a string (if specified)."); } - return > this.select(value => Series.toString(value, formatString)); + return >this.select(value => Series.toString(value, formatString)); } /** @@ -4465,7 +4467,7 @@ export class Series implements ISeries */ - bake (): ISeries { + bake(): ISeries { if (this.getContent().isBaked) { // Already baked. @@ -4504,7 +4506,7 @@ export class Series implements ISeries { AColumn: value.NestedValue }); // Extract a nested value and produce a dataframe from it. * */ - inflate (selector?: SelectorWithIndexFn): IDataFrame { + inflate(selector?: SelectorWithIndexFn): IDataFrame { if (selector) { if (!isFunction(selector)) throw new Error("Expected 'selector' parameter to Series.inflate to be a selector function."); @@ -4522,9 +4524,9 @@ export class Series implements ISeries(() => { const content = this.getContent(); return { - values: > content.values, + values: >content.values, index: content.index, - pairs: > content.pairs, + pairs: >content.pairs, }; }); } @@ -4539,9 +4541,9 @@ export class Series implements ISeries> this.filter(value => value !== null && value !== undefined); + const numberSeries = >this.filter(value => value !== null && value !== undefined); - if (numberSeries.any(value => typeof(value) !== "number")) { + if (numberSeries.any(value => typeof (value) !== "number")) { throw new Error(`Expected series to contain only numbers, you should parse this series or filter out non-number values.`); } @@ -4563,7 +4565,7 @@ export class Series implements ISeries */ - static sum (series: ISeries): number { + static sum(series: ISeries): number { return series.sum(); } @@ -4578,7 +4580,7 @@ export class Series implements ISeries */ - sum (): number { + sum(): number { const numberSeries = this.asNumberSeries(); if (numberSeries.none()) { @@ -4609,10 +4611,10 @@ export class Series implements ISeries */ - static average (series: ISeries): number { + static average(series: ISeries): number { return series.average(); } - + /** * Average the values in a series and returns the result * @@ -4626,7 +4628,7 @@ export class Series implements ISeries */ - average (): number { + average(): number { return this.mean(); } @@ -4645,10 +4647,10 @@ export class Series implements ISeries */ - static mean (series: ISeries): number { + static mean(series: ISeries): number { return series.mean(); } - + /** * Computes and returns the mean value of a set of values. * @@ -4660,7 +4662,7 @@ export class Series implements ISeries */ - mean (): number { + mean(): number { const numberSeries = this.asNumberSeries(); if (numberSeries.none()) { @@ -4680,7 +4682,7 @@ export class Series implements ISeries implements ISeries */ - static median (series: ISeries): number { + static median(series: ISeries): number { return series.median(); } @@ -4713,7 +4715,7 @@ export class Series implements ISeries */ - median (): number { + median(): number { const numberSeries = this.asNumberSeries(); const count = numberSeries.count(); @@ -4726,7 +4728,7 @@ export class Series implements ISeries implements ISeries */ - static mode (series: ISeries): any { + static mode(series: ISeries): any { return series.mode(); } @@ -4765,7 +4767,7 @@ export class Series implements ISeries */ - mode (): any { + mode(): any { const numberSeries = this.asNumberSeries(); if (numberSeries.none()) { @@ -4775,7 +4777,7 @@ export class Series implements ISeries(); for (const value of numberSeries) { - if (lookup.has(value)) { + if (lookup.has(value)) { lookup.set(value, lookup.get(value)! + 1); } else { @@ -4791,7 +4793,7 @@ export class Series implements ISeries implements ISeries implements ISeries */ - static variance (series: ISeries): number { + static variance(series: ISeries): number { return series.variance(); } - + /** * Get the (population) variance of number values in the series. * @@ -4843,7 +4845,7 @@ export class Series implements ISeries */ - variance (): number { + variance(): number { if (this.none()) { return 0; @@ -4868,10 +4870,10 @@ export class Series implements ISeries */ - static std (series: ISeries): number { + static std(series: ISeries): number { return series.std(); } - + /** * Get the (population) standard deviation of number values in the series. * @@ -4883,7 +4885,7 @@ export class Series implements ISeries */ - std (): number { + std(): number { if (this.none()) { return 0; @@ -4904,8 +4906,8 @@ export class Series implements ISeries */ - standardize (): ISeries { - + standardize(): ISeries { + if (this.none()) { // There are no values in the input series. return new Series(); @@ -4939,10 +4941,10 @@ export class Series implements ISeries */ - static sampleVariance (series: ISeries): number { + static sampleVariance(series: ISeries): number { return series.sampleVariance(); } - + /** * Get the (sample) variance of number values in the series. * @@ -4954,7 +4956,7 @@ export class Series implements ISeries */ - sampleVariance (): number { + sampleVariance(): number { if (this.none()) { return 0; @@ -4979,10 +4981,10 @@ export class Series implements ISeries */ - static sampleStd (series: ISeries): number { + static sampleStd(series: ISeries): number { return series.sampleStd(); } - + /** * Get the (sample) standard deviation of number values in the series. * @@ -4994,7 +4996,7 @@ export class Series implements ISeries */ - sampleStd (): number { + sampleStd(): number { if (this.none()) { return 0; @@ -5015,8 +5017,8 @@ export class Series implements ISeries */ - sampleStandardize (): ISeries { - + sampleStandardize(): ISeries { + if (this.none()) { // There are no values in the input series. return new Series(); @@ -5050,7 +5052,7 @@ export class Series implements ISeries */ - static min (series: ISeries): number { + static min(series: ISeries): number { return series.min(); } @@ -5065,7 +5067,7 @@ export class Series implements ISeries */ - min (): number { + min(): number { let min: number | undefined; @@ -5100,10 +5102,10 @@ export class Series implements ISeries */ - static max (series: ISeries): number { + static max(series: ISeries): number { return series.max(); } - + /** * Get the max value in the series. * @@ -5115,7 +5117,7 @@ export class Series implements ISeries */ - max (): number { + max(): number { let max: number | undefined; @@ -5150,10 +5152,10 @@ export class Series implements ISeries */ - static range (series: ISeries): number { + static range(series: ISeries): number { return series.range(); } - + /** * Get the range of values in the series. * @@ -5165,10 +5167,10 @@ export class Series implements ISeries */ - range (): number { + range(): number { return this.max() - this.min(); } - + /** * Invert the sign of every number value in the series. * This assumes that the input series contains numbers. @@ -5181,12 +5183,12 @@ export class Series implements ISeries */ - invert (): ISeries { + invert(): ISeries { return this .asNumberSeries() .select(value => { return -value; - }); + }); } /** @@ -5205,7 +5207,7 @@ export class Series implements ISeries */ - counter (predicate: PredicateFn): ISeries { + counter(predicate: PredicateFn): ISeries { return this.groupSequentialBy(predicate) .selectMany((group, i) => { if (predicate(group.first())) { @@ -5220,11 +5222,11 @@ export class Series implements ISeries pair[0]) .select(pair => pair[1]) as any as ISeries; } - + /** * Gets a new series in reverse order. * @@ -5236,7 +5238,7 @@ export class Series implements ISeries */ - reverse (): ISeries { + reverse(): ISeries { return new Series(() => ({ values: new ReverseIterable(this.getContent().values), @@ -5266,11 +5268,11 @@ export class Series implements ISeries Math.floor(value / 10)); // Lump values into buckets of 10. * */ - distinct (selector?: SelectorFn): ISeries { + distinct(selector?: SelectorFn): ISeries { return new Series(() => ({ values: new DistinctIterable(this.getContent().values, selector), - pairs: new DistinctIterable<[IndexT, ValueT],ToT>(this.getContent().pairs, (pair: [IndexT, ValueT]): ToT => selector && selector(pair[1]) || pair[1]) + pairs: new DistinctIterable<[IndexT, ValueT], ToT>(this.getContent().pairs, (pair: [IndexT, ValueT]): ToT => selector && selector(pair[1]) || pair[1]) })); } @@ -5294,16 +5296,16 @@ export class Series implements ISeries */ - groupBy (selector: SelectorWithIndexFn): ISeries> { + groupBy(selector: SelectorWithIndexFn): ISeries> { if (!isFunction(selector)) throw new Error("Expected 'selector' parameter to 'Series.groupBy' to be a selector function that determines the value to group the series by."); return new Series>(() => { const groups: any[] = []; // Each group, in order of discovery. const groupMap: any = {}; // Group map, records groups by key. - + let valueIndex = 0; - + for (const pair of this.getContent().pairs) { const groupKey = selector(pair[1], valueIndex); ++valueIndex; @@ -5321,10 +5323,10 @@ export class Series implements ISeries new Series({ pairs: group })) - }; + }; }); } - + /** * Collects values in the series into a new series of groups based on if the values are the same or according to a user-defined selector function. * @@ -5352,16 +5354,16 @@ export class Series implements ISeries - */ - groupSequentialBy (selector?: SelectorFn): ISeries> { + */ + groupSequentialBy(selector?: SelectorFn): ISeries> { if (selector) { if (!isFunction(selector)) throw new Error("Expected 'selector' parameter to 'Series.groupSequentialBy' to be a selector function that determines the value to group the series by.") } else { - selector = value => value; + selector = value => value; } - + return this.variableWindow((a: ValueT, b: ValueT): boolean => selector!(a) === selector!(b)); } @@ -5372,11 +5374,11 @@ export class Series implements ISeries (series: ISeries[]): ISeries { + static concat(series: ISeries[]): ISeries { if (!isArray(series)) throw new Error("Expected 'series' parameter to 'Series.concat' to be an array of series."); return new Series(() => { - const upcast = []> series; // Upcast so that we can access private index, values and pairs. + const upcast = []>series; // Upcast so that we can access private index, values and pairs. const contents = upcast.map(series => series.getContent()); return { values: new ConcatIterable(contents.map(content => content.values)), @@ -5384,7 +5386,7 @@ export class Series implements ISeries implements ISeries - */ - concat (...series: (ISeries[]|ISeries)[]): ISeries { + */ + concat(...series: (ISeries[] | ISeries)[]): ISeries { const concatInput: ISeries[] = [this]; for (const input of series) { @@ -5439,7 +5441,7 @@ export class Series implements ISeries(concatInput); } - + /** * Zip together multiple series to create a new series. * Preserves the index of the first series. @@ -5449,7 +5451,7 @@ export class Series implements ISeries (series: Iterable>, zipper: ZipNFn): ISeries { + static zip(series: Iterable>, zipper: ZipNFn): ISeries { const input = Array.from(series); @@ -5463,16 +5465,16 @@ export class Series implements ISeries(() => { - const firstSeriesUpCast = > firstSeries; - const upcast = []> input; // Upcast so that we can access private index, values and pairs. - + const firstSeriesUpCast = >firstSeries; + const upcast = []>input; // Upcast so that we can access private index, values and pairs. + return { - index: > firstSeriesUpCast.getContent().index, + index: >firstSeriesUpCast.getContent().index, values: new ZipIterable(upcast.map(s => s.getContent().values), zipper), }; }); } - + /** * Merge together multiple series to create a new series. * Preserves the index of the first series. @@ -5489,16 +5491,16 @@ export class Series implements ISeries valueA + valueB); * - */ - zip (s2: ISeries, zipper: Zip2Fn ): ISeries; - zip (s2: ISeries, s3: ISeries, zipper: Zip3Fn ): ISeries; - zip (s2: ISeries, s3: ISeries, s4: ISeries, zipper: Zip3Fn ): ISeries; - zip (...args: any[]): ISeries { - - const selector: Function = args[args.length-1]; - const input: ISeries[] = [this].concat(args.slice(0, args.length-1)); + */ + zip(s2: ISeries, zipper: Zip2Fn): ISeries; + zip(s2: ISeries, s3: ISeries, zipper: Zip3Fn): ISeries; + zip(s2: ISeries, s3: ISeries, s4: ISeries, zipper: Zip3Fn): ISeries; + zip(...args: any[]): ISeries { + + const selector: Function = args[args.length - 1]; + const input: ISeries[] = [this].concat(args.slice(0, args.length - 1)); return Series.zip(input, values => selector(...values)); - } + } /** * Sorts the series in ascending order by a value defined by the user-defined selector function. @@ -5519,13 +5521,13 @@ export class Series implements ISeries value.NestedValue); * */ - orderBy (selector: SelectorWithIndexFn): IOrderedSeries { + orderBy(selector: SelectorWithIndexFn): IOrderedSeries { const content = this.getContent(); return new OrderedSeries({ - values: content.values, - pairs: content.pairs, - selector: selector, - direction: Direction.Ascending, + values: content.values, + pairs: content.pairs, + selector: selector, + direction: Direction.Ascending, parent: null, }); } @@ -5549,17 +5551,17 @@ export class Series implements ISeries value.NestedValue); * */ - orderByDescending (selector: SelectorWithIndexFn): IOrderedSeries { + orderByDescending(selector: SelectorWithIndexFn): IOrderedSeries { const content = this.getContent(); return new OrderedSeries({ - values: content.values, - pairs: content.pairs, - selector: selector, - direction: Direction.Descending, + values: content.values, + pairs: content.pairs, + selector: selector, + direction: Direction.Descending, parent: null, }); } - + /** * Creates a new series by merging two input dataframes. * The resulting series contains the union of value from the two input series. @@ -5610,10 +5612,10 @@ export class Series implements ISeries * */ - union ( - other: ISeries, - selector?: SelectorFn): - ISeries { + union( + other: ISeries, + selector?: SelectorFn): + ISeries { if (selector) { if (!isFunction(selector)) throw new Error("Expected optional 'selector' parameter to 'Series.union' to be a selector function."); @@ -5653,34 +5655,34 @@ export class Series implements ISeries customerRecord.CustomerId * ); * - */ - intersection ( - inner: ISeries, + */ + intersection( + inner: ISeries, outerSelector?: SelectorFn, - innerSelector?: SelectorFn): - ISeries { + innerSelector?: SelectorFn): + ISeries { if (outerSelector) { if (!isFunction(outerSelector)) throw new Error("Expected optional 'outerSelector' parameter to 'Series.intersection' to be a function."); } else { - outerSelector = value => value; + outerSelector = value => value; } - + if (innerSelector) { if (!isFunction(innerSelector)) throw new Error("Expected optional 'innerSelector' parameter to 'Series.intersection' to be a function."); } else { - innerSelector = value => value; + innerSelector = value => value; } const outer = this; return outer.filter(outerValue => { - const outerKey = outerSelector!(outerValue); - return inner - .filter(innerValue => outerKey === innerSelector!(innerValue)) - .any(); - }); + const outerKey = outerSelector!(outerValue); + return inner + .filter(innerValue => outerKey === innerSelector!(innerValue)) + .any(); + }); } /** @@ -5713,72 +5715,72 @@ export class Series implements ISeries customerRecord.CustomerId * ); * - */ - except ( - inner: ISeries, + */ + except( + inner: ISeries, outerSelector?: SelectorFn, - innerSelector?: SelectorFn): - ISeries { + innerSelector?: SelectorFn): + ISeries { if (outerSelector) { if (!isFunction(outerSelector)) throw new Error("Expected optional 'outerSelector' parameter to 'Series.except' to be a function."); } else { - outerSelector = value => value; + outerSelector = value => value; } if (innerSelector) { if (!isFunction(innerSelector)) throw new Error("Expected optional 'innerSelector' parameter to 'Series.except' to be a function."); } else { - innerSelector = value => value; + innerSelector = value => value; } const outer = this; return outer.filter(outerValue => { - const outerKey = outerSelector!(outerValue); - return inner - .filter(innerValue => outerKey === innerSelector!(innerValue)) - .none(); - }); + const outerKey = outerSelector!(outerValue); + return inner + .filter(innerValue => outerKey === innerSelector!(innerValue)) + .none(); + }); } - /** - * Creates a new series by merging two input series. - * The resulting dataframe contains only those value that have matching keys in both input series. - * - * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series). - * @param outerKeySelector User-defined selector function that chooses the join key from the outer series. - * @param innerKeySelector User-defined selector function that chooses the join key from the inner series. - * @param resultSelector User-defined function that merges outer and inner values. - * - * @return Returns the new merged series. - * - * @example - *
-     * 
-     * // Join together two sets of customers to find those
-     * // that have bought both product A and product B.
-     * const customerWhoBoughtProductA = ...
-     * const customerWhoBoughtProductB = ...
-     * const customersWhoBoughtBothProductsDf = customerWhoBoughtProductA.join(
-     *          customerWhoBoughtProductB,
-     *          customerA => customerA.CustomerId, // Join key.
-     *          customerB => customerB.CustomerId, // Join key.
-     *          (customerA, customerB) => {
-     *              return {
-     *                  // ... merge the results ...
-     *              };
-     *          }
-     *      );
-     * 
- */ - join ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + /** + * Creates a new series by merging two input series. + * The resulting dataframe contains only those value that have matching keys in both input series. + * + * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series). + * @param outerKeySelector User-defined selector function that chooses the join key from the outer series. + * @param innerKeySelector User-defined selector function that chooses the join key from the inner series. + * @param resultSelector User-defined function that merges outer and inner values. + * + * @return Returns the new merged series. + * + * @example + *
+      * 
+      * // Join together two sets of customers to find those
+      * // that have bought both product A and product B.
+      * const customerWhoBoughtProductA = ...
+      * const customerWhoBoughtProductB = ...
+      * const customersWhoBoughtBothProductsDf = customerWhoBoughtProductA.join(
+      *          customerWhoBoughtProductB,
+      *          customerA => customerA.CustomerId, // Join key.
+      *          customerB => customerB.CustomerId, // Join key.
+      *          (customerA, customerB) => {
+      *              return {
+      *                  // ... merge the results ...
+      *              };
+      *          }
+      *      );
+      * 
+ */ + join( + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries { + ISeries { if (!isFunction(outerKeySelector)) throw new Error("Expected 'outerKeySelector' parameter of 'Series.join' to be a selector function."); if (!isFunction(innerKeySelector)) throw new Error("Expected 'innerKeySelector' parameter of 'Series.join' to be a selector function."); @@ -5790,21 +5792,21 @@ export class Series implements ISeries innerKeySelector(group.first()), + group => innerKeySelector(group.first()), group => group ); const outerContent = outer.getContent(); const output: ResultValueT[] = []; - + for (const outerValue of outer) { //TODO: There should be an enumerator that does this. const outerKey = outerKeySelector(outerValue); const innerGroup = innerMap[outerKey]; if (innerGroup) { for (const innerValue of innerGroup) { output.push(resultSelector(outerValue, innerValue)); - } + } } } @@ -5847,13 +5849,13 @@ export class Series implements ISeries - */ - joinOuter ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + */ + joinOuter( + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries { + ISeries { if (!isFunction(outerKeySelector)) throw new Error("Expected 'outerKeySelector' parameter of 'Series.joinOuter' to be a selector function."); if (!isFunction(innerKeySelector)) throw new Error("Expected 'innerKeySelector' parameter of 'Series.joinOuter' to be a selector function."); @@ -5913,12 +5915,12 @@ export class Series implements ISeries */ - joinOuterLeft ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + joinOuterLeft( + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries { + ISeries { if (!isFunction(outerKeySelector)) throw new Error("Expected 'outerKeySelector' parameter of 'Series.joinOuterLeft' to be a selector function."); if (!isFunction(innerKeySelector)) throw new Error("Expected 'innerKeySelector' parameter of 'Series.joinOuterLeft' to be a selector function."); @@ -5972,12 +5974,12 @@ export class Series implements ISeries */ - joinOuterRight ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + joinOuterRight( + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries { + ISeries { if (!isFunction(outerKeySelector)) throw new Error("Expected 'outerKeySelector' parameter of 'Series.joinOuterRight' to be a selector function."); if (!isFunction(innerKeySelector)) throw new Error("Expected 'innerKeySelector' parameter of 'Series.joinOuterRight' to be a selector function."); @@ -5995,7 +5997,7 @@ export class Series implements ISeries implements ISeries */ - truncateStrings (maxLength: number): ISeries { + truncateStrings(maxLength: number): ISeries { if (!isNumber(maxLength)) { throw new Error("Expected 'maxLength' parameter to 'Series.truncateStrings' to be a number."); @@ -6048,7 +6050,7 @@ export class Series implements ISeries */ - round (numDecimalPlaces?: number): ISeries { + round(numDecimalPlaces?: number): ISeries { if (numDecimalPlaces !== undefined) { if (!isNumber(numDecimalPlaces)) { @@ -6058,7 +6060,7 @@ export class Series implements ISeries { if (isNumber(value)) { return parseFloat(value.toFixed(numDecimalPlaces)); @@ -6084,7 +6086,7 @@ export class Series implements ISeries */ - insertPair (pair: [IndexT, ValueT]): ISeries { + insertPair(pair: [IndexT, ValueT]): ISeries { if (!isArray(pair)) throw new Error("Expected 'pair' parameter to 'Series.insertPair' to be an array."); if (pair.length !== 2) throw new Error("Expected 'pair' parameter to 'Series.insertPair' to be an array with two elements. The first element is the index, the second is the value."); @@ -6107,7 +6109,7 @@ export class Series implements ISeries */ - appendPair (pair: [IndexT, ValueT]): ISeries { + appendPair(pair: [IndexT, ValueT]): ISeries { if (!isArray(pair)) throw new Error("Expected 'pair' parameter to 'Series.appendPair' to be an array."); if (pair.length !== 2) throw new Error("Expected 'pair' parameter to 'Series.appendPair' to be an array with two elements. The first element is the index, the second is the value."); @@ -6117,7 +6119,7 @@ export class Series implements ISeries { + remove(index: IndexT): ISeries { return new Series(() => { const content = this.getContent(); @@ -6159,7 +6161,7 @@ export class Series implements ISeries */ - fillGaps (comparer: ComparerFn<[IndexT, ValueT], [IndexT, ValueT]>, generator: GapFillFn<[IndexT, ValueT], [IndexT, ValueT]>): ISeries { + fillGaps(comparer: ComparerFn<[IndexT, ValueT], [IndexT, ValueT]>, generator: GapFillFn<[IndexT, ValueT], [IndexT, ValueT]>): ISeries { if (!isFunction(comparer)) throw new Error("Expected 'comparer' parameter to 'Series.fillGaps' to be a comparer function that compares two values and returns a boolean.") if (!isFunction(generator)) throw new Error("Expected 'generator' parameter to 'Series.fillGaps' to be a generator function that takes two values and returns an array of generated pairs to span the gap.") @@ -6173,7 +6175,7 @@ export class Series implements ISeries implements ISeries */ - defaultIfEmpty (defaultSequence: ValueT[] | ISeries): ISeries { + defaultIfEmpty(defaultSequence: ValueT[] | ISeries): ISeries { if (this.none()) { if (defaultSequence instanceof Series) { - return > defaultSequence; + return >defaultSequence; } else if (isArray(defaultSequence)) { return new Series(defaultSequence); @@ -6217,7 +6219,7 @@ export class Series implements ISeries implements ISeries */ - detectTypes (): IDataFrame { + detectTypes(): IDataFrame { return new DataFrame(() => { const totalValues = this.count(); const typeFrequencies = this.select(value => { - let valueType: string = typeof(value); - if (valueType === "object") { - if (isDate(value)) { - valueType = "date"; - } + let valueType: string = typeof (value); + if (valueType === "object") { + if (isDate(value)) { + valueType = "date"; } - return valueType; - }) + } + return valueType; + }) .aggregate({}, (accumulated: any, valueType: string) => { var typeInfo = accumulated[valueType]; if (!typeInfo) { @@ -6288,7 +6290,7 @@ export class Series implements ISeries */ - detectValues (): IDataFrame { + detectValues(): IDataFrame { return new DataFrame(() => { const totalValues = this.count(); @@ -6336,7 +6338,7 @@ export class Series implements ISeries */ - bucket (numBuckets: number): IDataFrame { + bucket(numBuckets: number): IDataFrame { console.warn(`Series.bucket is deprecated and will be removed in the future.`); @@ -6352,18 +6354,18 @@ export class Series implements ISeries { - var bucket = Math.floor((v - min) / width); - var bucketMin = (bucket * width) + min; - return { - Value: v, - Bucket: bucket, - Min: bucketMin, - Mid: bucketMin + (width*0.5), - Max: bucketMin + width, - }; - }) + var bucket = Math.floor((v - min) / width); + var bucketMin = (bucket * width) + min; + return { + Value: v, + Bucket: bucket, + Min: bucketMin, + Mid: bucketMin + (width * 0.5), + Max: bucketMin + width, + }; + }) .inflate(); } @@ -6396,7 +6398,7 @@ export class Series implements ISeries */ - frequency (options?: IFrequencyTableOptions): IDataFrame { + frequency(options?: IFrequencyTableOptions): IDataFrame { if (this.none()) { return new DataFrame(); @@ -6446,13 +6448,13 @@ export class Series implements ISeries(numGroups); @@ -6466,7 +6468,7 @@ export class Series implements ISeries implements ISeries implements ISeries implements ISeries implements ISeries { * @hidden * A series that has been ordered. */ -class OrderedSeries +class OrderedSeries extends Series implements IOrderedSeries { @@ -6600,14 +6602,14 @@ class OrderedSeries // // Helper function to create a sort spec. // - private static makeSortSpec (sortLevel: number, selector: SortSelectorFn, direction: Direction): ISortSpec { + private static makeSortSpec(sortLevel: number, selector: SortSelectorFn, direction: Direction): ISortSpec { return { sortLevel: sortLevel, selector: selector, direction: direction }; } // // Helper function to make a sort selector for pairs, this captures the parent correct when generating the closure. // - private static makePairsSelector (selector: SortSelectorFn): SortSelectorFn { + private static makePairsSelector(selector: SortSelectorFn): SortSelectorFn { return (pair: any, index: number) => selector(pair[1], index); } @@ -6658,12 +6660,12 @@ class OrderedSeries * const ordered = sales.orderBy(sale => sale.SalesPerson).thenBy(sale => sale.Amount); * */ - thenBy (selector: SelectorWithIndexFn): IOrderedSeries { + thenBy(selector: SelectorWithIndexFn): IOrderedSeries { return new OrderedSeries({ - values: this.config.values, - pairs: this.config.pairs, - selector: selector, - direction: Direction.Ascending, + values: this.config.values, + pairs: this.config.pairs, + selector: selector, + direction: Direction.Ascending, parent: this, }); } @@ -6682,12 +6684,12 @@ class OrderedSeries * const ordered = sales.orderBy(sale => sale.SalesPerson).thenByDescending(sale => sale.Amount); * */ - thenByDescending (selector: SelectorWithIndexFn): IOrderedSeries { + thenByDescending(selector: SelectorWithIndexFn): IOrderedSeries { return new OrderedSeries({ values: this.config.values, - pairs: this.config.pairs, - selector: selector, - direction: Direction.Descending, + pairs: this.config.pairs, + selector: selector, + direction: Direction.Descending, parent: this }); } diff --git a/src/test/series.test.ts b/src/test/series.test.ts index f5067a9..a8b0f9d 100644 --- a/src/test/series.test.ts +++ b/src/test/series.test.ts @@ -83,6 +83,29 @@ describe('Series', () => { expect(series.toArray()).to.eql([10, 20]); }); + it('Series.toArray({includeNulls: true}) does not strip null values', () => { + + var series = new Series([10, null, 20, null]); + expect(series.toArray({ includeNulls: true })).to.eql([10, null, 20, null]); + }); + + it('Series.toArray({includeNulls: true}) strips undefined values', () => { + + var series = new Series([10, undefined, 20, undefined]); + expect(series.toArray({ includeNulls: true })).to.eql([10, 20]); + }); + + it('Series.toArray({includeNulls: false}) strips null values', () => { + + var series = new Series([10, null, 20, null]); + expect(series.toArray({ includeNulls: false })).to.eql([10, 20]); + }); + + it('Series.toArray({includeNulls: false}) strips undefined values', () => { + + var series = new Series([10, undefined, 20, undefined]); + expect(series.toArray({ includeNulls: false })).to.eql([10, 20]); + }); it('Series.toPairs strips undefined values', () => { From e5d903af7cea785b173f9cc683656131c2de3652 Mon Sep 17 00:00:00 2001 From: max Date: Mon, 11 Mar 2024 16:51:45 -0400 Subject: [PATCH 2/4] Added options signature to toArray method on ISeries interface. --- src/lib/series.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/series.ts b/src/lib/series.ts index f137735..8e91260 100644 --- a/src/lib/series.ts +++ b/src/lib/series.ts @@ -394,7 +394,7 @@ export interface ISeries extends Iterable * const values = series.toArray(); * */ - toArray(): ValueT[]; + toArray(options?: { includeNulls?: boolean }): ValueT[]; /** * Retreive the index, values pairs from the series as an array. From e47ccfb196b1be276b006b269b322f966e49f0d4 Mon Sep 17 00:00:00 2001 From: max Date: Tue, 12 Mar 2024 17:31:51 -0400 Subject: [PATCH 3/4] Added spaces between named functions and parentheses --- src/lib/series.ts | 490 +++++++++++++++++++++++----------------------- 1 file changed, 245 insertions(+), 245 deletions(-) diff --git a/src/lib/series.ts b/src/lib/series.ts index 8e91260..15538e9 100644 --- a/src/lib/series.ts +++ b/src/lib/series.ts @@ -286,7 +286,7 @@ export interface ISeries extends Iterable * } * */ - [Symbol.iterator](): Iterator; + [Symbol.iterator] (): Iterator; /** * Cast the value of the series to a new type. @@ -300,7 +300,7 @@ export interface ISeries extends Iterable * const castSeries = series.cast(); * */ - cast(): ISeries; + cast (): ISeries; /** * Get the index for the series. @@ -313,7 +313,7 @@ export interface ISeries extends Iterable * const index = series.getIndex(); * */ - getIndex(): IIndex; + getIndex (): IIndex; /** * Apply a new {@link Index} to the series. @@ -346,7 +346,7 @@ export interface ISeries extends Iterable * const indexedSeries = series.withIndex(value => value + 20); * */ - withIndex(newIndex: Iterable | SelectorFn): ISeries; + withIndex (newIndex: Iterable | SelectorFn): ISeries; /** * Resets the {@link Index} of the series back to the default zero-based sequential integer index. @@ -359,7 +359,7 @@ export interface ISeries extends Iterable * const seriesWithResetIndex = series.resetIndex(); * */ - resetIndex(): ISeries; + resetIndex (): ISeries; /** * Merge one or more series into this series. @@ -381,7 +381,7 @@ export interface ISeries extends Iterable * const mergedSeries = series1.merge(series2, series3, etc); * */ - merge(...args: any[]): ISeries; + merge (...args: any[]): ISeries; /** * Extract values from the series as an array. @@ -394,7 +394,7 @@ export interface ISeries extends Iterable * const values = series.toArray(); * */ - toArray(options?: { includeNulls?: boolean }): ValueT[]; + toArray (options?: { includeNulls?: boolean }): ValueT[]; /** * Retreive the index, values pairs from the series as an array. @@ -408,7 +408,7 @@ export interface ISeries extends Iterable * const pairs = series.toPairs(); * */ - toPairs(): ([IndexT, ValueT])[]; + toPairs (): ([IndexT, ValueT])[]; /** * Convert the series to a JavaScript object. @@ -427,7 +427,7 @@ export interface ISeries extends Iterable * ); * */ - toObject(keySelector: (value: ValueT) => KeyT, valueSelector: (value: ValueT) => FieldT): OutT; + toObject (keySelector: (value: ValueT) => KeyT, valueSelector: (value: ValueT) => FieldT): OutT; /** * Transforms an input series, generating a new series. @@ -453,7 +453,7 @@ export interface ISeries extends Iterable * console.log(transformed.toString()); * */ - select(transformer: SelectorWithIndexFn): ISeries; + select (transformer: SelectorWithIndexFn): ISeries; /** * Transforms an input series, generating a new series. @@ -477,7 +477,7 @@ export interface ISeries extends Iterable * console.log(transformed.toString()); * */ - map(transformer: SelectorWithIndexFn): ISeries; + map (transformer: SelectorWithIndexFn): ISeries; /** * Transforms and flattens an input series, generating a new series. @@ -507,7 +507,7 @@ export interface ISeries extends Iterable * console.log(transformed.toString()); * */ - selectMany(transformer: SelectorWithIndexFn>): ISeries; + selectMany (transformer: SelectorWithIndexFn>): ISeries; /** * Transforms and flattens an input series, generating a new series. @@ -535,7 +535,7 @@ export interface ISeries extends Iterable * console.log(transformed.toString()); * */ - flatMap(transformer: SelectorWithIndexFn>): ISeries; + flatMap (transformer: SelectorWithIndexFn>): ISeries; /** * Partition a series into a {@link Series} of *data windows*. @@ -562,7 +562,7 @@ export interface ISeries extends Iterable * console.log(weeklySales.toString()); * */ - window(period: number, whichIndex?: WhichIndex): ISeries>; + window (period: number, whichIndex?: WhichIndex): ISeries>; /** * Partition a series into a new series of *rolling data windows*. @@ -581,7 +581,7 @@ export interface ISeries extends Iterable * console.log(rollingWeeklySales.toString()); * */ - rollingWindow(period: number, whichIndex?: WhichIndex): ISeries>; + rollingWindow (period: number, whichIndex?: WhichIndex): ISeries>; /** * Partition a series into a new series of variable-length *data windows* @@ -606,7 +606,7 @@ export interface ISeries extends Iterable * * const variableWindows = series.variableWindow(rowComparer); */ - variableWindow(comparer: ComparerFn): ISeries>; + variableWindow (comparer: ComparerFn): ISeries>; /** * Eliminates adjacent duplicate values. @@ -627,7 +627,7 @@ export interface ISeries extends Iterable * const seriesWithDuplicateRowsRemoved = series.sequentialDistinct(value => value.someNestedField); * */ - sequentialDistinct(selector: SelectorFn): ISeries; + sequentialDistinct (selector: SelectorFn): ISeries; /** * Reduces the values in the series to a single result. @@ -671,7 +671,7 @@ export interface ISeries extends Iterable * }); * */ - aggregate(seedOrSelector: AggregateFn | ToT, selector?: AggregateFn): ToT; + aggregate (seedOrSelector: AggregateFn | ToT, selector?: AggregateFn): ToT; /** * Reduces the values in the series to a single result. @@ -704,7 +704,7 @@ export interface ISeries extends Iterable * ); * */ - reduce(reducer: AggregateFn, seed?: ToT): ToT; + reduce (reducer: AggregateFn, seed?: ToT): ToT; /** * Compute the absolute range of values in each period. @@ -722,7 +722,7 @@ export interface ISeries extends Iterable * const volatility = closingPrice.amountRange(5); * */ - amountRange(period: number, whichIndex?: WhichIndex): ISeries; + amountRange (period: number, whichIndex?: WhichIndex): ISeries; /** * Compute the range of values in each period in proportion to the latest value. @@ -743,7 +743,7 @@ export interface ISeries extends Iterable * const proportionVolatility = closingPrice.proportionRange(5); * */ - proportionRange(period: number, whichIndex?: WhichIndex): ISeries; + proportionRange (period: number, whichIndex?: WhichIndex): ISeries; /** * Compute the range of values in each period in proportion to the latest value. @@ -764,7 +764,7 @@ export interface ISeries extends Iterable * const percentVolatility = closingPrice.percentRange(5); * */ - percentRange(period: number, whichIndex?: WhichIndex): ISeries; + percentRange (period: number, whichIndex?: WhichIndex): ISeries; /** * Compute the amount of change between pairs or sets of values in the series. @@ -787,7 +787,7 @@ export interface ISeries extends Iterable * const amountChanged = salesFigures.amountChanged(7); // Amount that sales has changed, week to week. * */ - amountChange(period?: number, whichIndex?: WhichIndex): ISeries; + amountChange (period?: number, whichIndex?: WhichIndex): ISeries; /** * Compute the proportion change between pairs or sets of values in the series. @@ -811,7 +811,7 @@ export interface ISeries extends Iterable * const proportionChanged = salesFigures.amountChanged(7); // Proportion that sales has changed, week to week. * */ - proportionChange(period?: number, whichIndex?: WhichIndex): ISeries; + proportionChange (period?: number, whichIndex?: WhichIndex): ISeries; /** * Compute the percentage change between pairs or sets of values in the series. @@ -835,7 +835,7 @@ export interface ISeries extends Iterable * const percentChanged = salesFigures.amountChanged(7); // Percent that sales has changed, week to week. * */ - percentChange(period?: number, whichIndex?: WhichIndex): ISeries; + percentChange (period?: number, whichIndex?: WhichIndex): ISeries; /** * For each period, compute the proportion of values that are less than the last value in the period. @@ -856,7 +856,7 @@ export interface ISeries extends Iterable * const proportionRank = series.proportionRank(100); * */ - proportionRank(period?: number): ISeries; + proportionRank (period?: number): ISeries; /** * For each period, compute the percent of values that are less than the last value in the period. @@ -877,14 +877,14 @@ export interface ISeries extends Iterable * const percentRank = series.percentRank(100); * */ - percentRank(period?: number): ISeries; + percentRank (period?: number): ISeries; /** * Generates a cumulative sum across a series. * * @returns Returns a new series that is the cumulative sum of values across the input series. */ - cumsum(): ISeries; + cumsum (): ISeries; /** * Skip a number of values in the series. @@ -899,7 +899,7 @@ export interface ISeries extends Iterable * const seriesWithRowsSkipped = series.skip(10); // Skip 10 rows in the original series. * */ - skip(numValues: number): ISeries; + skip (numValues: number): ISeries; /** * Skips values in the series while a condition evaluates to true or truthy. @@ -914,7 +914,7 @@ export interface ISeries extends Iterable * const seriesWithRowsSkipped = series.skipWhile(salesFigure => salesFigure > 100); // Skip initial sales figure that are less than 100. * */ - skipWhile(predicate: PredicateFn): ISeries; + skipWhile (predicate: PredicateFn): ISeries; /** * Skips values in the series untils a condition evaluates to true or truthy. @@ -929,7 +929,7 @@ export interface ISeries extends Iterable * const seriesWithRowsSkipped = series.skipUntil(salesFigure => salesFigure > 100); // Skip initial sales figures unitl we see one greater than 100. * */ - skipUntil(predicate: PredicateFn): ISeries; + skipUntil (predicate: PredicateFn): ISeries; /** * Take a number of values from the series. @@ -944,7 +944,7 @@ export interface ISeries extends Iterable * const seriesWithRowsTaken = series.take(15); // Take only the first 15 values from the original series. * */ - take(numRows: number): ISeries; + take (numRows: number): ISeries; /** * Takes values from the series while a condition evaluates to true or truthy. @@ -959,7 +959,7 @@ export interface ISeries extends Iterable * const seriesWithRowsTaken = series.takeWhile(salesFigure => salesFigure > 100); // Take only initial sales figures that are greater than 100. * */ - takeWhile(predicate: PredicateFn): ISeries; + takeWhile (predicate: PredicateFn): ISeries; /** * Takes values from the series until a condition evaluates to true or truthy. @@ -974,7 +974,7 @@ export interface ISeries extends Iterable * const seriesWithRowsTaken = series.takeUntil(salesFigure => salesFigure > 100); // Take all initial sales figures until we see one that is greater than 100. * */ - takeUntil(predicate: PredicateFn): ISeries; + takeUntil (predicate: PredicateFn): ISeries; /** * Count the number of values in the seriese @@ -987,7 +987,7 @@ export interface ISeries extends Iterable * const numValues = series.count(); * */ - count(): number; + count (): number; /** * Get the first value of the series. @@ -1000,7 +1000,7 @@ export interface ISeries extends Iterable * const firstValue = series.first(); * */ - first(): ValueT; + first (): ValueT; /** * Get the last value of the series. @@ -1013,7 +1013,7 @@ export interface ISeries extends Iterable * const lastValue = series.last(); * */ - last(): ValueT; + last (): ValueT; /** * Get the value, if there is one, with the specified index. @@ -1036,7 +1036,7 @@ export interface ISeries extends Iterable * const value = series.at(date); * */ - at(index: IndexT): ValueT | undefined; + at (index: IndexT): ValueT | undefined; /** * Get X value from the start of the series. @@ -1052,7 +1052,7 @@ export interface ISeries extends Iterable * const sample = series.head(10); // Take a sample of 10 values from the start of the series. * */ - head(numValues: number): ISeries; + head (numValues: number): ISeries; /** * Get X values from the end of the series. @@ -1068,7 +1068,7 @@ export interface ISeries extends Iterable * const sample = series.tail(12); // Take a sample of 12 values from the end of the series. * */ - tail(numValues: number): ISeries; + tail (numValues: number): ISeries; /** * Filter the series using user-defined predicate function. @@ -1089,7 +1089,7 @@ export interface ISeries extends Iterable * console.log(filtered.toArray()); * */ - where(predicate: PredicateFn): ISeries; + where (predicate: PredicateFn): ISeries; /** * Filter the series through a user-defined predicate function. @@ -1108,7 +1108,7 @@ export interface ISeries extends Iterable * console.log(filtered.toArray()); * */ - filter(predicate: PredicateFn): ISeries; + filter (predicate: PredicateFn): ISeries; /** * Invoke a callback function for each value in the series. @@ -1125,7 +1125,7 @@ export interface ISeries extends Iterable * }); * */ - forEach(callback: CallbackFn): ISeries; + forEach (callback: CallbackFn): ISeries; /** * Evaluates a predicate function for every value in the series to determine @@ -1141,7 +1141,7 @@ export interface ISeries extends Iterable * const result = series.all(salesFigure => salesFigure > 100); // Returns true if all sales figures are greater than 100. * */ - all(predicate: PredicateFn): boolean; + all (predicate: PredicateFn): boolean; /** * Evaluates a predicate function for every value in the series to determine @@ -1167,7 +1167,7 @@ export interface ISeries extends Iterable * const result = series.any(); // Do we have any sales figures at all? * */ - any(predicate?: PredicateFn): boolean; + any (predicate?: PredicateFn): boolean; /** * Evaluates a predicate function for every value in the series to determine @@ -1191,7 +1191,7 @@ export interface ISeries extends Iterable * const result = series.none(); // Do we have zero sales figures? * */ - none(predicate?: PredicateFn): boolean; + none (predicate?: PredicateFn): boolean; /** * Gets a new series containing all values starting at or after the specified index value. @@ -1221,7 +1221,7 @@ export interface ISeries extends Iterable * const result = timeSeries.startAt(new Date(2016, 5, 4)); * */ - startAt(indexValue: IndexT): ISeries; + startAt (indexValue: IndexT): ISeries; /** * Gets a new series containing all values up until and including the specified index value (inclusive). @@ -1251,7 +1251,7 @@ export interface ISeries extends Iterable * const result = timeSeries.endAt(new Date(2016, 5, 4)); * */ - endAt(indexValue: IndexT): ISeries; + endAt (indexValue: IndexT): ISeries; /** * Gets a new series containing all values up to the specified index value (exclusive). @@ -1281,7 +1281,7 @@ export interface ISeries extends Iterable * const result = timeSeries.before(new Date(2016, 5, 4)); * */ - before(indexValue: IndexT): ISeries; + before (indexValue: IndexT): ISeries; /** * Gets a new series containing all values after the specified index value (exclusive). @@ -1311,7 +1311,7 @@ export interface ISeries extends Iterable * const result = timeSeries.after(new Date(2016, 5, 4)); * */ - after(indexValue: IndexT): ISeries; + after (indexValue: IndexT): ISeries; /** * Gets a new series containing all values between the specified index values (inclusive). @@ -1342,7 +1342,7 @@ export interface ISeries extends Iterable * const result = timeSeries.after(new Date(2016, 5, 4), new Date(2016, 5, 22)); * */ - between(startIndexValue: IndexT, endIndexValue: IndexT): ISeries; + between (startIndexValue: IndexT, endIndexValue: IndexT): ISeries; /** * Format the series for display as a string. @@ -1356,7 +1356,7 @@ export interface ISeries extends Iterable * console.log(series.toString()); * */ - toString(): string; + toString (): string; /** * Parse a series with string values and convert it to a series with int values. @@ -1369,7 +1369,7 @@ export interface ISeries extends Iterable * const parsed = series.parseInts(); * */ - parseInts(): ISeries; + parseInts (): ISeries; /** * Parse a series with string values and convert it to a series with float values. @@ -1382,7 +1382,7 @@ export interface ISeries extends Iterable * const parsed = series.parseFloats(); * */ - parseFloats(): ISeries; + parseFloats (): ISeries; /** * Parse a series with string values and convert it to a series with date values. @@ -1400,7 +1400,7 @@ export interface ISeries extends Iterable * const parsed = series.parseDates(); * */ - parseDates(formatString?: string): ISeries; + parseDates (formatString?: string): ISeries; /** * Convert a series of values of different types to a series containing string values. @@ -1427,7 +1427,7 @@ export interface ISeries extends Iterable * const result = series.toStrings("0.00"); * */ - toStrings(formatString?: string): ISeries; + toStrings (formatString?: string): ISeries; /** * Forces lazy evaluation to complete and 'bakes' the series into memory. @@ -1440,7 +1440,7 @@ export interface ISeries extends Iterable * const baked = series.bake(); * */ - bake(): ISeries; + bake (): ISeries; /** * Converts (inflates) a series to a {@link DataFrame}. @@ -1467,7 +1467,7 @@ export interface ISeries extends Iterable * const dataframe = series.inflate(value => { AColumn: value.NestedValue }); // Extract a nested value and produce a dataframe from it. * */ - inflate(selector?: SelectorWithIndexFn): IDataFrame; + inflate (selector?: SelectorWithIndexFn): IDataFrame; /** * Sum the values in a series and returns the result. @@ -1480,7 +1480,7 @@ export interface ISeries extends Iterable * const totalSales = salesFigures.sum(); * */ - sum(): number; + sum (): number; /** * Average the values in a series and returns the result. @@ -1495,7 +1495,7 @@ export interface ISeries extends Iterable * const averageSales = salesFigures.average(); * */ - average(): number; + average (): number; /** * Computes and returns the mean value of a set of values. @@ -1508,7 +1508,7 @@ export interface ISeries extends Iterable * const averageSales = salesFigures.mean(); * */ - mean(): number; + mean (): number; /** * Get the median value in the series. @@ -1522,7 +1522,7 @@ export interface ISeries extends Iterable * const medianSales = salesFigures.median(); * */ - median(): number; + median (): number; /** * Get the mode of the values in the series. @@ -1537,7 +1537,7 @@ export interface ISeries extends Iterable * const modeSales = salesFigures.mode(); * */ - mode(): any; + mode (): any; /** * Get the variance of number values in the series. @@ -1550,7 +1550,7 @@ export interface ISeries extends Iterable * const salesVariance = salesFigures.variance(); * */ - variance(): number; + variance (): number; /** * Get the standard deviation of number values in the series. @@ -1563,7 +1563,7 @@ export interface ISeries extends Iterable * const salesStdDev = salesFigures.std(); * */ - std(): number; + std (): number; /** * Standardize a series of numbers by converting each "standard deviations from the mean". @@ -1577,7 +1577,7 @@ export interface ISeries extends Iterable * const standardizedSeries = series.standardize(); * */ - standardize(): ISeries; + standardize (): ISeries; /** * Get the (sample) variance of number values in the series. @@ -1590,7 +1590,7 @@ export interface ISeries extends Iterable * const salesVariance = salesFigures.variance(); * */ - sampleVariance(): number; + sampleVariance (): number; /** * Get the (sample) standard deviation of number values in the series. @@ -1603,7 +1603,7 @@ export interface ISeries extends Iterable * const salesStdDev = salesFigures.sampleStd(); * */ - sampleStd(): number; + sampleStd (): number; /** * Standardize a series of numbers by converting each "standard deviations from the mean". @@ -1617,7 +1617,7 @@ export interface ISeries extends Iterable * const standardizedSeries = series.sampleStandardize(); * */ - sampleStandardize(): ISeries; + sampleStandardize (): ISeries; /** * Get the min value in the series. @@ -1630,7 +1630,7 @@ export interface ISeries extends Iterable * const minSales = salesFigures.min(); * */ - min(): number; + min (): number; /** * Get the max value in the series. @@ -1643,7 +1643,7 @@ export interface ISeries extends Iterable * const maxSales = salesFigures.max(); * */ - max(): number; + max (): number; /** * Get the range of values in the series. @@ -1656,7 +1656,7 @@ export interface ISeries extends Iterable * const range = salesFigures.range(); * */ - range(): number; + range (): number; /** * Invert the sign of every number value in the series. @@ -1670,7 +1670,7 @@ export interface ISeries extends Iterable * const inverted = series.invert(); * */ - invert(): ISeries; + invert (): ISeries; /** * Counts the number of sequential values where the predicate evaluates to truthy. @@ -1688,7 +1688,7 @@ export interface ISeries extends Iterable * console.log(counted.toString()); * */ - counter(predicate: PredicateFn): ISeries; + counter (predicate: PredicateFn): ISeries; /** * Gets a new series in reverse order. @@ -1701,7 +1701,7 @@ export interface ISeries extends Iterable * const reversed = series.reverse(); * */ - reverse(): ISeries; + reverse (): ISeries; /** * Returns only the set of values in the series that are distinct. @@ -1724,7 +1724,7 @@ export interface ISeries extends Iterable * const bucketedValues = series.distinct(value => Math.floor(value / 10)); // Lump values into buckets of 10. * */ - distinct(selector?: SelectorFn): ISeries; + distinct (selector?: SelectorFn): ISeries; /** * Collects values in the series into a new series of groups according to a user-defined selector function. @@ -1746,7 +1746,7 @@ export interface ISeries extends Iterable * } * */ - groupBy(selector: SelectorFn): ISeries>; + groupBy (selector: SelectorFn): ISeries>; /** * Collects values in the series into a new series of groups based on if the values are the same or according to a user-defined selector function. @@ -1776,7 +1776,7 @@ export interface ISeries extends Iterable * } * */ - groupSequentialBy(selector?: SelectorFn): ISeries>; + groupSequentialBy (selector?: SelectorFn): ISeries>; /** * Concatenate multiple other series onto this series. @@ -1816,7 +1816,7 @@ export interface ISeries extends Iterable * const concatenated = a.concat(otherSeries); * */ - concat(...series: (ISeries[] | ISeries)[]): ISeries; + concat (...series: (ISeries[] | ISeries)[]): ISeries; /** * Zip together multiple series to create a new series. @@ -1835,10 +1835,10 @@ export interface ISeries extends Iterable * const zipped = a.zip(b (valueA, valueB) => valueA + valueB); * */ - zip(s2: ISeries, zipper: Zip2Fn): ISeries; - zip(s2: ISeries, s3: ISeries, zipper: Zip3Fn): ISeries; - zip(s2: ISeries, s3: ISeries, s4: ISeries, zipper: Zip3Fn): ISeries; - zip(...args: any[]): ISeries; + zip (s2: ISeries, zipper: Zip2Fn): ISeries; + zip (s2: ISeries, s3: ISeries, zipper: Zip3Fn): ISeries; + zip (s2: ISeries, s3: ISeries, s4: ISeries, zipper: Zip3Fn): ISeries; + zip (...args: any[]): ISeries; /** * Sorts the series in ascending order by a value defined by the user-defined selector function. @@ -1859,7 +1859,7 @@ export interface ISeries extends Iterable * const orderedSeries = series.orderBy(value => value.NestedValue); * */ - orderBy(selector: SelectorWithIndexFn): IOrderedSeries; + orderBy (selector: SelectorWithIndexFn): IOrderedSeries; /** * Sorts the series in descending order by a value defined by the user-defined selector function. @@ -1880,7 +1880,7 @@ export interface ISeries extends Iterable * const orderedSeries = series.orderByDescending(value => value.NestedValue); * */ - orderByDescending(selector: SelectorWithIndexFn): IOrderedSeries; + orderByDescending (selector: SelectorWithIndexFn): IOrderedSeries; /** * Creates a new series by merging two input dataframes. @@ -1932,7 +1932,7 @@ export interface ISeries extends Iterable * * */ - union( + union ( other: ISeries, selector?: SelectorFn): ISeries; @@ -1969,7 +1969,7 @@ export interface ISeries extends Iterable * ); * */ - intersection( + intersection ( inner: ISeries, outerSelector?: SelectorFn, innerSelector?: SelectorFn): @@ -2006,7 +2006,7 @@ export interface ISeries extends Iterable * ); * */ - except( + except ( inner: ISeries, outerSelector?: SelectorFn, innerSelector?: SelectorFn): @@ -2042,7 +2042,7 @@ export interface ISeries extends Iterable * ); * */ - join( + join ( inner: ISeries, outerKeySelector: SelectorFn, innerKeySelector: SelectorFn, @@ -2083,7 +2083,7 @@ export interface ISeries extends Iterable * ); * */ - joinOuter( + joinOuter ( inner: ISeries, outerKeySelector: SelectorFn, innerKeySelector: SelectorFn, @@ -2124,7 +2124,7 @@ export interface ISeries extends Iterable * ); * */ - joinOuterLeft( + joinOuterLeft ( inner: ISeries, outerKeySelector: SelectorFn, innerKeySelector: SelectorFn, @@ -2165,7 +2165,7 @@ export interface ISeries extends Iterable * ); * */ - joinOuterRight( + joinOuterRight ( inner: ISeries, outerKeySelector: SelectorFn, innerKeySelector: SelectorFn, @@ -2185,7 +2185,7 @@ export interface ISeries extends Iterable * const truncated = series.truncateStrings(10); // Truncate all string values to max length of 10 characters. * */ - truncateStrings(maxLength: number): ISeries; + truncateStrings (maxLength: number): ISeries; /** * Produces a new series with all number values rounded to the specified number of places. @@ -2208,7 +2208,7 @@ export interface ISeries extends Iterable * const rounded = series.round(3); // Round numbers to three decimal places. * */ - round(numDecimalPlaces?: number): ISeries; + round (numDecimalPlaces?: number): ISeries; /** * Insert a pair at the start of the series. @@ -2226,7 +2226,7 @@ export interface ISeries extends Iterable * const insertedSeries = series.insertPair([newIndex, newRows]); * */ - insertPair(pair: [IndexT, ValueT]): ISeries; + insertPair (pair: [IndexT, ValueT]): ISeries; /** * Append a pair to the end of a series. @@ -2244,12 +2244,12 @@ export interface ISeries extends Iterable * const appendedSeries = series.appendPair([newIndex, newRows]); * */ - appendPair(pair: [IndexT, ValueT]): ISeries; + appendPair (pair: [IndexT, ValueT]): ISeries; /** * Removes values from the series by index. */ - remove(index: IndexT): ISeries; + remove (index: IndexT): ISeries; /** * Fill gaps in a series. @@ -2283,7 +2283,7 @@ export interface ISeries extends Iterable * var sequenceWithoutGaps = sequenceWithGaps.fillGaps(gapExists, gapFiller); * */ - fillGaps(comparer: ComparerFn<[IndexT, ValueT], [IndexT, ValueT]>, generator: GapFillFn<[IndexT, ValueT], [IndexT, ValueT]>): ISeries; + fillGaps (comparer: ComparerFn<[IndexT, ValueT], [IndexT, ValueT]>, generator: GapFillFn<[IndexT, ValueT], [IndexT, ValueT]>): ISeries; /** * Returns the specified default series if the input series is empty. @@ -2308,7 +2308,7 @@ export interface ISeries extends Iterable * expect(nonEmptySeries.defaultIfEmpty(defaultSeries)).to.eql(nonEmptySeries); * */ - defaultIfEmpty(defaultSequence: ValueT[] | ISeries): ISeries; + defaultIfEmpty (defaultSequence: ValueT[] | ISeries): ISeries; /** * Detect the the frequency of the types of the values in the series. @@ -2323,7 +2323,7 @@ export interface ISeries extends Iterable * console.log(dataTypes.toString()); * */ - detectTypes(): IDataFrame; + detectTypes (): IDataFrame; /** * Detect the frequency of the values in the series. @@ -2338,7 +2338,7 @@ export interface ISeries extends Iterable * console.log(dataValues.toString()); * */ - detectValues(): IDataFrame; + detectValues (): IDataFrame; /** * Organise all values in the series into the specified number of buckets. @@ -2357,7 +2357,7 @@ export interface ISeries extends Iterable * console.log(buckets.toString()); * */ - bucket(numBuckets: number): IDataFrame; + bucket (numBuckets: number): IDataFrame; /** * Counts frequencies in the series to produce a frequency table. @@ -2388,7 +2388,7 @@ export interface ISeries extends Iterable * console.log(frequencyTable.toArray()); * */ - frequency(options?: IFrequencyTableOptions): IDataFrame; + frequency (options?: IFrequencyTableOptions): IDataFrame; } /** @@ -2410,7 +2410,7 @@ export interface IOrderedSeries exte * const ordered = sales.orderBy(sale => sale.SalesPerson).thenBy(sale => sale.Amount); * */ - thenBy(selector: SelectorWithIndexFn): IOrderedSeries; + thenBy (selector: SelectorWithIndexFn): IOrderedSeries; /** * Applys additional sorting (descending) to an already sorted series. @@ -2426,7 +2426,7 @@ export interface IOrderedSeries exte * const ordered = sales.orderBy(sale => sale.SalesPerson).thenByDescending(sale => sale.Amount); * */ - thenByDescending(selector: SelectorWithIndexFn): IOrderedSeries; + thenByDescending (selector: SelectorWithIndexFn): IOrderedSeries; } // @@ -2483,14 +2483,14 @@ export class Series implements ISeries(iterator: Iterator): ISeriesContent { + private static initFromIterator (iterator: Iterator): ISeriesContent { return Series.initFromIterable(new CachedIteratorIterable(iterator)); } // // Initialise series content from an iterable of values. // - private static initFromIterable(arr: Iterable): ISeriesContent { + private static initFromIterable (arr: Iterable): ISeriesContent { return { index: Series.defaultCountIterable, values: arr, @@ -2502,7 +2502,7 @@ export class Series implements ISeries(): ISeriesContent { + private static initEmpty (): ISeriesContent { return { index: Series.defaultEmptyIterable, values: Series.defaultEmptyIterable, @@ -2514,14 +2514,14 @@ export class Series implements ISeries implements ISeries(input: any, fieldName: string): void { + private static checkIterable (input: any, fieldName: string): void { if (Series.isIterable(input)) { // Assume it's an iterable. // Ok @@ -2543,7 +2543,7 @@ export class Series implements ISeries(config: ISeriesConfig): ISeriesContent { + private static initFromConfig (config: ISeriesConfig): ISeriesContent { let index: Iterable; let values: Iterable; @@ -2681,7 +2681,7 @@ export class Series implements ISeries implements ISeries { + private getContent (): ISeriesContent { this.lazyInit(); return this.content!; } @@ -2698,7 +2698,7 @@ export class Series implements ISeries(); for (const pair of this.getContent().pairs) { @@ -2724,7 +2724,7 @@ export class Series implements ISeries */ - [Symbol.iterator](): Iterator { + [Symbol.iterator] (): Iterator { return this.getContent().values[Symbol.iterator](); } @@ -2740,7 +2740,7 @@ export class Series implements ISeries(); * */ - cast(): ISeries { + cast (): ISeries { return this as any as ISeries; } @@ -2755,7 +2755,7 @@ export class Series implements ISeries */ - getIndex(): IIndex { + getIndex (): IIndex { return new Index(() => ({ values: this.getContent().index })); } @@ -2790,7 +2790,7 @@ export class Series implements ISeries value + 20); * */ - withIndex(newIndex: Iterable | SelectorFn): ISeries { + withIndex (newIndex: Iterable | SelectorFn): ISeries { if (isFunction(newIndex)) { return new Series(() => ({ @@ -2819,7 +2819,7 @@ export class Series implements ISeries */ - resetIndex(): ISeries { + resetIndex (): ISeries { return new Series(() => ({ values: this.getContent().values // Just strip the index. })); @@ -2840,7 +2840,7 @@ export class Series implements ISeries */ - static merge(series: Iterable>): ISeries { + static merge (series: Iterable>): ISeries { const rowMap = new Map(); const numSeries = Array.from(series).length; //TODO: Be nice not to have to do this. @@ -2898,7 +2898,7 @@ export class Series implements ISeries */ - merge(...args: any[]): ISeries { + merge (...args: any[]): ISeries { return Series.merge([this].concat(args)); } @@ -2913,7 +2913,7 @@ export class Series implements ISeries */ - toArray(options?: { includeNulls?: boolean }): any[] { + toArray (options?: { includeNulls?: boolean }): any[] { const values = []; for (const value of this.getContent().values) { if (options && options.includeNulls && value !== undefined) { @@ -2937,7 +2937,7 @@ export class Series implements ISeries */ - toPairs(): ([IndexT, ValueT])[] { + toPairs (): ([IndexT, ValueT])[] { const pairs = []; for (const pair of this.getContent().pairs) { if (pair[1] !== undefined && pair[1] !== null) { @@ -2964,7 +2964,7 @@ export class Series implements ISeries */ - toObject(keySelector: (value: ValueT) => KeyT, valueSelector: (value: ValueT) => FieldT): OutT { + toObject (keySelector: (value: ValueT) => KeyT, valueSelector: (value: ValueT) => FieldT): OutT { if (!isFunction(keySelector)) throw new Error("Expected 'keySelector' parameter to Series.toObject to be a function."); if (!isFunction(valueSelector)) throw new Error("Expected 'valueSelector' parameter to Series.toObject to be a function."); @@ -2996,7 +2996,7 @@ export class Series implements ISeries */ - select(transformer: SelectorWithIndexFn): ISeries { + select (transformer: SelectorWithIndexFn): ISeries { if (!isFunction(transformer)) throw new Error("Expected 'transformer' parameter to 'Series.select' to be a function."); return this.map(transformer); @@ -3024,7 +3024,7 @@ export class Series implements ISeries */ - map(transformer: SelectorWithIndexFn): ISeries { + map (transformer: SelectorWithIndexFn): ISeries { if (!isFunction(transformer)) throw new Error("Expected 'transformer' parameter to 'Series.map' to be a function."); return new Series(() => { @@ -3064,7 +3064,7 @@ export class Series implements ISeries */ - selectMany(transformer: SelectorWithIndexFn>): ISeries { + selectMany (transformer: SelectorWithIndexFn>): ISeries { if (!isFunction(transformer)) throw new Error("Expected 'transformer' parameter to 'Series.selectMany' to be a function."); return this.flatMap(transformer); @@ -3096,7 +3096,7 @@ export class Series implements ISeries */ - flatMap(transformer: SelectorWithIndexFn>): ISeries { + flatMap (transformer: SelectorWithIndexFn>): ISeries { if (!isFunction(transformer)) throw new Error("Expected 'transformer' parameter to 'Series.flatMap' to be a function."); return new Series(() => ({ @@ -3141,7 +3141,7 @@ export class Series implements ISeries */ - window(period: number, whichIndex?: WhichIndex): ISeries> { + window (period: number, whichIndex?: WhichIndex): ISeries> { if (!isNumber(period)) throw new Error("Expected 'period' parameter to 'Series.window' to be a number."); @@ -3167,7 +3167,7 @@ export class Series implements ISeries */ - rollingWindow(period: number, whichIndex?: WhichIndex): ISeries> { + rollingWindow (period: number, whichIndex?: WhichIndex): ISeries> { if (!isNumber(period)) throw new Error("Expected 'period' parameter to 'Series.rollingWindow' to be a number."); @@ -3199,7 +3199,7 @@ export class Series implements ISeries): ISeries> { + variableWindow (comparer: ComparerFn): ISeries> { if (!isFunction(comparer)) throw new Error("Expected 'comparer' parameter to 'Series.variableWindow' to be a function.") @@ -3227,7 +3227,7 @@ export class Series implements ISeries value.someNestedField); * */ - sequentialDistinct(selector?: SelectorFn): ISeries { + sequentialDistinct (selector?: SelectorFn): ISeries { if (selector) { if (!isFunction(selector)) throw new Error("Expected 'selector' parameter to 'Series.sequentialDistinct' to be a selector function that determines the value to compare for duplicates.") @@ -3286,7 +3286,7 @@ export class Series implements ISeries */ - aggregate(seedOrSelector: AggregateFn | ToT, selector?: AggregateFn): ToT { + aggregate (seedOrSelector: AggregateFn | ToT, selector?: AggregateFn): ToT { if (isFunction(seedOrSelector) && !selector) { return this.skip(1).aggregate(this.first(), seedOrSelector); @@ -3335,7 +3335,7 @@ export class Series implements ISeries */ - reduce(reducer: AggregateFn, seed?: ToT): ToT { + reduce (reducer: AggregateFn, seed?: ToT): ToT { if (!isFunction(reducer)) throw new Error("Expected 'reducer' parameter to `Series.reduce` to be a function."); let accum = seed; @@ -3369,7 +3369,7 @@ export class Series implements ISeries */ - amountRange(period: number, whichIndex?: WhichIndex): ISeries { + amountRange (period: number, whichIndex?: WhichIndex): ISeries { return (>this) // Have to assume this is a number series. .rollingWindow(period, whichIndex) .select(window => window.max() - window.min()); @@ -3393,7 +3393,7 @@ export class Series implements ISeries */ - proportionRange(period: number, whichIndex?: WhichIndex): ISeries { + proportionRange (period: number, whichIndex?: WhichIndex): ISeries { return (>this) // Have to assume this is a number series. .rollingWindow(period, whichIndex) .select(window => (window.max() - window.min()) / window.last()); @@ -3417,7 +3417,7 @@ export class Series implements ISeries */ - percentRange(period: number, whichIndex?: WhichIndex): ISeries { + percentRange (period: number, whichIndex?: WhichIndex): ISeries { return this.proportionRange(period, whichIndex).select(v => v * 100); } @@ -3441,7 +3441,7 @@ export class Series implements ISeries */ - amountChange(period?: number, whichIndex?: WhichIndex): ISeries { + amountChange (period?: number, whichIndex?: WhichIndex): ISeries { return (>this) // Have to assume this is a number series. .rollingWindow(period === undefined ? 2 : period, whichIndex) .select(window => window.last() - window.first()); @@ -3468,7 +3468,7 @@ export class Series implements ISeries */ - proportionChange(period?: number, whichIndex?: WhichIndex): ISeries { + proportionChange (period?: number, whichIndex?: WhichIndex): ISeries { return (>this) // Have to assume this is a number series. .rollingWindow(period === undefined ? 2 : period, whichIndex) .select(window => (window.last() - window.first()) / window.first()); @@ -3495,7 +3495,7 @@ export class Series implements ISeries */ - percentChange(period?: number, whichIndex?: WhichIndex): ISeries { + percentChange (period?: number, whichIndex?: WhichIndex): ISeries { return this.proportionChange(period, whichIndex).select(v => v * 100); } @@ -3518,7 +3518,7 @@ export class Series implements ISeries */ - proportionRank(period?: number): ISeries { + proportionRank (period?: number): ISeries { if (period === undefined) { period = 2; } @@ -3555,7 +3555,7 @@ export class Series implements ISeries */ - percentRank(period?: number): ISeries { + percentRank (period?: number): ISeries { if (period === undefined) { period = 2; } @@ -3572,7 +3572,7 @@ export class Series implements ISeries { + cumsum (): ISeries { return new Series(() => { let working = 0; const pairs: any[][] = this.toPairs(); @@ -3594,7 +3594,7 @@ export class Series implements ISeries */ - skip(numValues: number): ISeries { + skip (numValues: number): ISeries { return new Series(() => ({ values: new SkipIterable(this.getContent().values, numValues), index: new SkipIterable(this.getContent().index, numValues), @@ -3615,7 +3615,7 @@ export class Series implements ISeries salesFigure > 100); // Skip initial sales figure that are less than 100. * */ - skipWhile(predicate: PredicateFn): ISeries { + skipWhile (predicate: PredicateFn): ISeries { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.skipWhile' function to be a predicate function that returns true/false."); return new Series(() => ({ @@ -3637,7 +3637,7 @@ export class Series implements ISeries salesFigure > 100); // Skip initial sales figures unitl we see one greater than 100. * */ - skipUntil(predicate: PredicateFn): ISeries { + skipUntil (predicate: PredicateFn): ISeries { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.skipUntil' function to be a predicate function that returns true/false."); return this.skipWhile(value => !predicate(value)); @@ -3656,7 +3656,7 @@ export class Series implements ISeries */ - take(numRows: number): ISeries { + take (numRows: number): ISeries { if (!isNumber(numRows)) throw new Error("Expected 'numRows' parameter to 'Series.take' function to be a number."); return new Series(() => ({ @@ -3679,7 +3679,7 @@ export class Series implements ISeries salesFigure > 100); // Take only initial sales figures that are greater than 100. * */ - takeWhile(predicate: PredicateFn): ISeries { + takeWhile (predicate: PredicateFn): ISeries { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.takeWhile' function to be a predicate function that returns true/false."); return new Series(() => ({ @@ -3701,7 +3701,7 @@ export class Series implements ISeries salesFigure > 100); // Take all initial sales figures until we see one that is greater than 100. * */ - takeUntil(predicate: PredicateFn): ISeries { + takeUntil (predicate: PredicateFn): ISeries { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.takeUntil' function to be a predicate function that returns true/false."); return this.takeWhile(value => !predicate(value)); @@ -3722,7 +3722,7 @@ export class Series implements ISeries */ - static count(series: ISeries): number { + static count (series: ISeries): number { return series.count(); } @@ -3737,7 +3737,7 @@ export class Series implements ISeries */ - count(): number { + count (): number { let total = 0; for (const value of this.getContent().values) { @@ -3757,7 +3757,7 @@ export class Series implements ISeries */ - first(): ValueT { + first (): ValueT { for (const value of this) { return value; // Only need the first value. @@ -3777,7 +3777,7 @@ export class Series implements ISeries */ - last(): ValueT { + last (): ValueT { let lastValue = null; @@ -3813,7 +3813,7 @@ export class Series implements ISeries */ - at(index: IndexT): ValueT | undefined { + at (index: IndexT): ValueT | undefined { if (this.none()) { return undefined; @@ -3836,7 +3836,7 @@ export class Series implements ISeries */ - head(numValues: number): ISeries { + head (numValues: number): ISeries { if (!isNumber(numValues)) throw new Error("Expected 'numValues' parameter to 'Series.head' function to be a number."); @@ -3862,7 +3862,7 @@ export class Series implements ISeries */ - tail(numValues: number): ISeries { + tail (numValues: number): ISeries { if (!isNumber(numValues)) throw new Error("Expected 'numValues' parameter to 'Series.tail' function to be a number."); @@ -3893,7 +3893,7 @@ export class Series implements ISeries */ - where(predicate: PredicateFn): ISeries { + where (predicate: PredicateFn): ISeries { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.where' to be a function."); return this.filter(predicate); @@ -3916,7 +3916,7 @@ export class Series implements ISeries */ - filter(predicate: PredicateFn): ISeries { + filter (predicate: PredicateFn): ISeries { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.filter' to be a function."); return new Series(() => { @@ -3943,7 +3943,7 @@ export class Series implements ISeries */ - forEach(callback: CallbackFn): ISeries { + forEach (callback: CallbackFn): ISeries { if (!isFunction(callback)) throw new Error("Expected 'callback' parameter to 'Series.forEach' to be a function."); let index = 0; @@ -3968,7 +3968,7 @@ export class Series implements ISeries salesFigure > 100); // Returns true if all sales figures are greater than 100. * */ - all(predicate: PredicateFn): boolean { + all (predicate: PredicateFn): boolean { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.all' to be a function.") let count = 0; @@ -4008,7 +4008,7 @@ export class Series implements ISeries */ - any(predicate?: PredicateFn): boolean { + any (predicate?: PredicateFn): boolean { if (predicate) { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.any' to be a function.") } @@ -4052,7 +4052,7 @@ export class Series implements ISeries */ - none(predicate?: PredicateFn): boolean { + none (predicate?: PredicateFn): boolean { if (predicate) { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.none' to be a function.") @@ -4103,7 +4103,7 @@ export class Series implements ISeries */ - startAt(indexValue: IndexT): ISeries { + startAt (indexValue: IndexT): ISeries { return new Series(() => { const lessThan = this.getIndex().getLessThan(); return { @@ -4141,7 +4141,7 @@ export class Series implements ISeries */ - endAt(indexValue: IndexT): ISeries { + endAt (indexValue: IndexT): ISeries { return new Series(() => { const lessThanOrEqualTo = this.getIndex().getLessThanOrEqualTo(); return { @@ -4179,7 +4179,7 @@ export class Series implements ISeries */ - before(indexValue: IndexT): ISeries { + before (indexValue: IndexT): ISeries { return new Series(() => { const lessThan = this.getIndex().getLessThan(); return { @@ -4217,7 +4217,7 @@ export class Series implements ISeries */ - after(indexValue: IndexT): ISeries { + after (indexValue: IndexT): ISeries { return new Series(() => { const lessThanOrEqualTo = this.getIndex().getLessThanOrEqualTo(); return { @@ -4256,7 +4256,7 @@ export class Series implements ISeries */ - between(startIndexValue: IndexT, endIndexValue: IndexT): ISeries { + between (startIndexValue: IndexT, endIndexValue: IndexT): ISeries { return this.startAt(startIndexValue).endAt(endIndexValue); } @@ -4272,7 +4272,7 @@ export class Series implements ISeries */ - toString(): string { + toString (): string { const header = ["__index__", "__value__"]; const rows = this.toPairs(); @@ -4293,7 +4293,7 @@ export class Series implements ISeries implements ISeries */ - parseInts(): ISeries { + parseInts (): ISeries { return >this.select(Series.parseInt); } // // Helper function to parse a string to a float. // - static parseFloat(value: any | undefined | null, valueIndex: number): number | undefined { + static parseFloat (value: any | undefined | null, valueIndex: number): number | undefined { if (value === undefined || value === null) { return undefined; } @@ -4354,14 +4354,14 @@ export class Series implements ISeries */ - parseFloats(): ISeries { + parseFloats (): ISeries { return >this.select(Series.parseFloat); } // // Helper function to parse a string to a date. // - static parseDate(value: any | undefined | null, valueIndex: number, formatString?: string): Date | undefined { + static parseDate (value: any | undefined | null, valueIndex: number, formatString?: string): Date | undefined { if (value === undefined || value === null) { return undefined; } @@ -4392,7 +4392,7 @@ export class Series implements ISeries */ - parseDates(formatString?: string): ISeries { + parseDates (formatString?: string): ISeries { if (formatString) { if (!isString(formatString)) throw new Error("Expected optional 'formatString' parameter to Series.parseDates to be a string (if specified)."); @@ -4404,7 +4404,7 @@ export class Series implements ISeries implements ISeries */ - toStrings(formatString?: string): ISeries { + toStrings (formatString?: string): ISeries { if (formatString) { if (!isString(formatString)) throw new Error("Expected optional 'formatString' parameter to Series.toStrings to be a string (if specified)."); @@ -4467,7 +4467,7 @@ export class Series implements ISeries */ - bake(): ISeries { + bake (): ISeries { if (this.getContent().isBaked) { // Already baked. @@ -4506,7 +4506,7 @@ export class Series implements ISeries { AColumn: value.NestedValue }); // Extract a nested value and produce a dataframe from it. * */ - inflate(selector?: SelectorWithIndexFn): IDataFrame { + inflate (selector?: SelectorWithIndexFn): IDataFrame { if (selector) { if (!isFunction(selector)) throw new Error("Expected 'selector' parameter to Series.inflate to be a selector function."); @@ -4536,7 +4536,7 @@ export class Series implements ISeries { + private asNumberSeries (): ISeries { // // From here: http://stackoverflow.com/questions/5275115/add-a-median-method-to-a-list // @@ -4565,7 +4565,7 @@ export class Series implements ISeries */ - static sum(series: ISeries): number { + static sum (series: ISeries): number { return series.sum(); } @@ -4580,7 +4580,7 @@ export class Series implements ISeries */ - sum(): number { + sum (): number { const numberSeries = this.asNumberSeries(); if (numberSeries.none()) { @@ -4611,7 +4611,7 @@ export class Series implements ISeries */ - static average(series: ISeries): number { + static average (series: ISeries): number { return series.average(); } @@ -4628,7 +4628,7 @@ export class Series implements ISeries */ - average(): number { + average (): number { return this.mean(); } @@ -4647,7 +4647,7 @@ export class Series implements ISeries */ - static mean(series: ISeries): number { + static mean (series: ISeries): number { return series.mean(); } @@ -4662,7 +4662,7 @@ export class Series implements ISeries */ - mean(): number { + mean (): number { const numberSeries = this.asNumberSeries(); if (numberSeries.none()) { @@ -4699,7 +4699,7 @@ export class Series implements ISeries */ - static median(series: ISeries): number { + static median (series: ISeries): number { return series.median(); } @@ -4715,7 +4715,7 @@ export class Series implements ISeries */ - median(): number { + median (): number { const numberSeries = this.asNumberSeries(); const count = numberSeries.count(); @@ -4750,7 +4750,7 @@ export class Series implements ISeries */ - static mode(series: ISeries): any { + static mode (series: ISeries): any { return series.mode(); } @@ -4767,7 +4767,7 @@ export class Series implements ISeries */ - mode(): any { + mode (): any { const numberSeries = this.asNumberSeries(); if (numberSeries.none()) { @@ -4793,7 +4793,7 @@ export class Series implements ISeries implements ISeries */ - static variance(series: ISeries): number { + static variance (series: ISeries): number { return series.variance(); } @@ -4845,7 +4845,7 @@ export class Series implements ISeries */ - variance(): number { + variance (): number { if (this.none()) { return 0; @@ -4870,7 +4870,7 @@ export class Series implements ISeries */ - static std(series: ISeries): number { + static std (series: ISeries): number { return series.std(); } @@ -4885,7 +4885,7 @@ export class Series implements ISeries */ - std(): number { + std (): number { if (this.none()) { return 0; @@ -4906,7 +4906,7 @@ export class Series implements ISeries */ - standardize(): ISeries { + standardize (): ISeries { if (this.none()) { // There are no values in the input series. @@ -4941,7 +4941,7 @@ export class Series implements ISeries */ - static sampleVariance(series: ISeries): number { + static sampleVariance (series: ISeries): number { return series.sampleVariance(); } @@ -4956,7 +4956,7 @@ export class Series implements ISeries */ - sampleVariance(): number { + sampleVariance (): number { if (this.none()) { return 0; @@ -4981,7 +4981,7 @@ export class Series implements ISeries */ - static sampleStd(series: ISeries): number { + static sampleStd (series: ISeries): number { return series.sampleStd(); } @@ -4996,7 +4996,7 @@ export class Series implements ISeries */ - sampleStd(): number { + sampleStd (): number { if (this.none()) { return 0; @@ -5017,7 +5017,7 @@ export class Series implements ISeries */ - sampleStandardize(): ISeries { + sampleStandardize (): ISeries { if (this.none()) { // There are no values in the input series. @@ -5052,7 +5052,7 @@ export class Series implements ISeries */ - static min(series: ISeries): number { + static min (series: ISeries): number { return series.min(); } @@ -5067,7 +5067,7 @@ export class Series implements ISeries */ - min(): number { + min (): number { let min: number | undefined; @@ -5102,7 +5102,7 @@ export class Series implements ISeries */ - static max(series: ISeries): number { + static max (series: ISeries): number { return series.max(); } @@ -5117,7 +5117,7 @@ export class Series implements ISeries */ - max(): number { + max (): number { let max: number | undefined; @@ -5152,7 +5152,7 @@ export class Series implements ISeries */ - static range(series: ISeries): number { + static range (series: ISeries): number { return series.range(); } @@ -5167,7 +5167,7 @@ export class Series implements ISeries */ - range(): number { + range (): number { return this.max() - this.min(); } @@ -5183,7 +5183,7 @@ export class Series implements ISeries */ - invert(): ISeries { + invert (): ISeries { return this .asNumberSeries() .select(value => { @@ -5207,7 +5207,7 @@ export class Series implements ISeries */ - counter(predicate: PredicateFn): ISeries { + counter (predicate: PredicateFn): ISeries { return this.groupSequentialBy(predicate) .selectMany((group, i) => { if (predicate(group.first())) { @@ -5238,7 +5238,7 @@ export class Series implements ISeries */ - reverse(): ISeries { + reverse (): ISeries { return new Series(() => ({ values: new ReverseIterable(this.getContent().values), @@ -5268,7 +5268,7 @@ export class Series implements ISeries Math.floor(value / 10)); // Lump values into buckets of 10. * */ - distinct(selector?: SelectorFn): ISeries { + distinct (selector?: SelectorFn): ISeries { return new Series(() => ({ values: new DistinctIterable(this.getContent().values, selector), @@ -5296,7 +5296,7 @@ export class Series implements ISeries */ - groupBy(selector: SelectorWithIndexFn): ISeries> { + groupBy (selector: SelectorWithIndexFn): ISeries> { if (!isFunction(selector)) throw new Error("Expected 'selector' parameter to 'Series.groupBy' to be a selector function that determines the value to group the series by."); @@ -5355,7 +5355,7 @@ export class Series implements ISeries */ - groupSequentialBy(selector?: SelectorFn): ISeries> { + groupSequentialBy (selector?: SelectorFn): ISeries> { if (selector) { if (!isFunction(selector)) throw new Error("Expected 'selector' parameter to 'Series.groupSequentialBy' to be a selector function that determines the value to group the series by.") @@ -5374,7 +5374,7 @@ export class Series implements ISeries(series: ISeries[]): ISeries { + static concat (series: ISeries[]): ISeries { if (!isArray(series)) throw new Error("Expected 'series' parameter to 'Series.concat' to be an array of series."); return new Series(() => { @@ -5425,7 +5425,7 @@ export class Series implements ISeries */ - concat(...series: (ISeries[] | ISeries)[]): ISeries { + concat (...series: (ISeries[] | ISeries)[]): ISeries { const concatInput: ISeries[] = [this]; for (const input of series) { @@ -5451,7 +5451,7 @@ export class Series implements ISeries(series: Iterable>, zipper: ZipNFn): ISeries { + static zip (series: Iterable>, zipper: ZipNFn): ISeries { const input = Array.from(series); @@ -5492,10 +5492,10 @@ export class Series implements ISeries valueA + valueB); * */ - zip(s2: ISeries, zipper: Zip2Fn): ISeries; - zip(s2: ISeries, s3: ISeries, zipper: Zip3Fn): ISeries; - zip(s2: ISeries, s3: ISeries, s4: ISeries, zipper: Zip3Fn): ISeries; - zip(...args: any[]): ISeries { + zip (s2: ISeries, zipper: Zip2Fn): ISeries; + zip (s2: ISeries, s3: ISeries, zipper: Zip3Fn): ISeries; + zip (s2: ISeries, s3: ISeries, s4: ISeries, zipper: Zip3Fn): ISeries; + zip (...args: any[]): ISeries { const selector: Function = args[args.length - 1]; const input: ISeries[] = [this].concat(args.slice(0, args.length - 1)); @@ -5521,7 +5521,7 @@ export class Series implements ISeries value.NestedValue); * */ - orderBy(selector: SelectorWithIndexFn): IOrderedSeries { + orderBy (selector: SelectorWithIndexFn): IOrderedSeries { const content = this.getContent(); return new OrderedSeries({ values: content.values, @@ -5551,7 +5551,7 @@ export class Series implements ISeries value.NestedValue); * */ - orderByDescending(selector: SelectorWithIndexFn): IOrderedSeries { + orderByDescending (selector: SelectorWithIndexFn): IOrderedSeries { const content = this.getContent(); return new OrderedSeries({ values: content.values, @@ -5612,7 +5612,7 @@ export class Series implements ISeries * */ - union( + union ( other: ISeries, selector?: SelectorFn): ISeries { @@ -5656,7 +5656,7 @@ export class Series implements ISeries */ - intersection( + intersection ( inner: ISeries, outerSelector?: SelectorFn, innerSelector?: SelectorFn): @@ -5716,7 +5716,7 @@ export class Series implements ISeries */ - except( + except ( inner: ISeries, outerSelector?: SelectorFn, innerSelector?: SelectorFn): @@ -5775,7 +5775,7 @@ export class Series implements ISeries */ - join( + join ( inner: ISeries, outerKeySelector: SelectorFn, innerKeySelector: SelectorFn, @@ -5850,7 +5850,7 @@ export class Series implements ISeries */ - joinOuter( + joinOuter ( inner: ISeries, outerKeySelector: SelectorFn, innerKeySelector: SelectorFn, @@ -5915,7 +5915,7 @@ export class Series implements ISeries */ - joinOuterLeft( + joinOuterLeft ( inner: ISeries, outerKeySelector: SelectorFn, innerKeySelector: SelectorFn, @@ -5974,7 +5974,7 @@ export class Series implements ISeries */ - joinOuterRight( + joinOuterRight ( inner: ISeries, outerKeySelector: SelectorFn, innerKeySelector: SelectorFn, @@ -6012,7 +6012,7 @@ export class Series implements ISeries */ - truncateStrings(maxLength: number): ISeries { + truncateStrings (maxLength: number): ISeries { if (!isNumber(maxLength)) { throw new Error("Expected 'maxLength' parameter to 'Series.truncateStrings' to be a number."); @@ -6050,7 +6050,7 @@ export class Series implements ISeries */ - round(numDecimalPlaces?: number): ISeries { + round (numDecimalPlaces?: number): ISeries { if (numDecimalPlaces !== undefined) { if (!isNumber(numDecimalPlaces)) { @@ -6086,7 +6086,7 @@ export class Series implements ISeries */ - insertPair(pair: [IndexT, ValueT]): ISeries { + insertPair (pair: [IndexT, ValueT]): ISeries { if (!isArray(pair)) throw new Error("Expected 'pair' parameter to 'Series.insertPair' to be an array."); if (pair.length !== 2) throw new Error("Expected 'pair' parameter to 'Series.insertPair' to be an array with two elements. The first element is the index, the second is the value."); @@ -6109,7 +6109,7 @@ export class Series implements ISeries */ - appendPair(pair: [IndexT, ValueT]): ISeries { + appendPair (pair: [IndexT, ValueT]): ISeries { if (!isArray(pair)) throw new Error("Expected 'pair' parameter to 'Series.appendPair' to be an array."); if (pair.length !== 2) throw new Error("Expected 'pair' parameter to 'Series.appendPair' to be an array with two elements. The first element is the index, the second is the value."); @@ -6119,7 +6119,7 @@ export class Series implements ISeries { + remove (index: IndexT): ISeries { return new Series(() => { const content = this.getContent(); @@ -6161,7 +6161,7 @@ export class Series implements ISeries */ - fillGaps(comparer: ComparerFn<[IndexT, ValueT], [IndexT, ValueT]>, generator: GapFillFn<[IndexT, ValueT], [IndexT, ValueT]>): ISeries { + fillGaps (comparer: ComparerFn<[IndexT, ValueT], [IndexT, ValueT]>, generator: GapFillFn<[IndexT, ValueT], [IndexT, ValueT]>): ISeries { if (!isFunction(comparer)) throw new Error("Expected 'comparer' parameter to 'Series.fillGaps' to be a comparer function that compares two values and returns a boolean.") if (!isFunction(generator)) throw new Error("Expected 'generator' parameter to 'Series.fillGaps' to be a generator function that takes two values and returns an array of generated pairs to span the gap.") @@ -6207,7 +6207,7 @@ export class Series implements ISeries */ - defaultIfEmpty(defaultSequence: ValueT[] | ISeries): ISeries { + defaultIfEmpty (defaultSequence: ValueT[] | ISeries): ISeries { if (this.none()) { if (defaultSequence instanceof Series) { @@ -6238,7 +6238,7 @@ export class Series implements ISeries */ - detectTypes(): IDataFrame { + detectTypes (): IDataFrame { return new DataFrame(() => { const totalValues = this.count(); @@ -6290,7 +6290,7 @@ export class Series implements ISeries */ - detectValues(): IDataFrame { + detectValues (): IDataFrame { return new DataFrame(() => { const totalValues = this.count(); @@ -6338,7 +6338,7 @@ export class Series implements ISeries */ - bucket(numBuckets: number): IDataFrame { + bucket (numBuckets: number): IDataFrame { console.warn(`Series.bucket is deprecated and will be removed in the future.`); @@ -6398,7 +6398,7 @@ export class Series implements ISeries */ - frequency(options?: IFrequencyTableOptions): IDataFrame { + frequency (options?: IFrequencyTableOptions): IDataFrame { if (this.none()) { return new DataFrame(); @@ -6549,7 +6549,7 @@ export class Series implements ISeries // // Helper function to create a sort spec. // - private static makeSortSpec(sortLevel: number, selector: SortSelectorFn, direction: Direction): ISortSpec { + private static makeSortSpec (sortLevel: number, selector: SortSelectorFn, direction: Direction): ISortSpec { return { sortLevel: sortLevel, selector: selector, direction: direction }; } // // Helper function to make a sort selector for pairs, this captures the parent correct when generating the closure. // - private static makePairsSelector(selector: SortSelectorFn): SortSelectorFn { + private static makePairsSelector (selector: SortSelectorFn): SortSelectorFn { return (pair: any, index: number) => selector(pair[1], index); } @@ -6660,7 +6660,7 @@ class OrderedSeries * const ordered = sales.orderBy(sale => sale.SalesPerson).thenBy(sale => sale.Amount); * */ - thenBy(selector: SelectorWithIndexFn): IOrderedSeries { + thenBy (selector: SelectorWithIndexFn): IOrderedSeries { return new OrderedSeries({ values: this.config.values, pairs: this.config.pairs, @@ -6684,7 +6684,7 @@ class OrderedSeries * const ordered = sales.orderBy(sale => sale.SalesPerson).thenByDescending(sale => sale.Amount); * */ - thenByDescending(selector: SelectorWithIndexFn): IOrderedSeries { + thenByDescending (selector: SelectorWithIndexFn): IOrderedSeries { return new OrderedSeries({ values: this.config.values, pairs: this.config.pairs, From 3f3fa223f818e50cc07e5f9e4c6caea0062deea8 Mon Sep 17 00:00:00 2001 From: max Date: Tue, 12 Mar 2024 17:39:11 -0400 Subject: [PATCH 4/4] Restored original format. --- src/lib/series.ts | 798 +++++++++++++++++++++++----------------------- 1 file changed, 399 insertions(+), 399 deletions(-) diff --git a/src/lib/series.ts b/src/lib/series.ts index 15538e9..5d0691d 100644 --- a/src/lib/series.ts +++ b/src/lib/series.ts @@ -1,20 +1,20 @@ -import { ArrayIterable } from './iterables/array-iterable'; -import { EmptyIterable } from './iterables/empty-iterable'; -import { CountIterable } from './iterables/count-iterable'; -import { MultiIterable } from './iterables/multi-iterable'; -import { SelectIterable } from './iterables/select-iterable'; -import { SelectManyIterable } from './iterables/select-many-iterable'; -import { TakeIterable } from './iterables/take-iterable'; -import { TakeWhileIterable } from './iterables/take-while-iterable'; -import { WhereIterable } from './iterables/where-iterable'; -import { ConcatIterable } from './iterables/concat-iterable'; -import { SeriesWindowIterable } from './iterables/series-window-iterable'; -import { ReverseIterable } from './iterables/reverse-iterable'; -import { ZipIterable } from './iterables/zip-iterable'; -import { DistinctIterable } from './iterables/distinct-iterable'; -import { SeriesRollingWindowIterable } from './iterables/series-rolling-window-iterable'; -import { SeriesVariableWindowIterable } from './iterables/series-variable-window-iterable'; -import { OrderedIterable, Direction, ISortSpec, SelectorFn as SortSelectorFn } from './iterables/ordered-iterable'; +import { ArrayIterable } from './iterables/array-iterable'; +import { EmptyIterable } from './iterables/empty-iterable'; +import { CountIterable } from './iterables/count-iterable'; +import { MultiIterable } from './iterables/multi-iterable'; +import { SelectIterable } from './iterables/select-iterable'; +import { SelectManyIterable } from './iterables/select-many-iterable'; +import { TakeIterable } from './iterables/take-iterable'; +import { TakeWhileIterable } from './iterables/take-while-iterable'; +import { WhereIterable } from './iterables/where-iterable'; +import { ConcatIterable } from './iterables/concat-iterable'; +import { SeriesWindowIterable } from './iterables/series-window-iterable'; +import { ReverseIterable } from './iterables/reverse-iterable'; +import { ZipIterable } from './iterables/zip-iterable'; +import { DistinctIterable } from './iterables/distinct-iterable'; +import { SeriesRollingWindowIterable } from './iterables/series-rolling-window-iterable'; +import { SeriesVariableWindowIterable } from './iterables/series-variable-window-iterable'; +import { OrderedIterable, Direction, ISortSpec, SelectorFn as SortSelectorFn } from './iterables/ordered-iterable'; import { IIndex, Index } from './index'; import { ExtractElementIterable } from './iterables/extract-element-iterable'; import { SkipIterable } from './iterables/skip-iterable'; @@ -80,7 +80,7 @@ export type SelectorWithIndexFn = (value: FromT, index: number) => T //TODO: The Zip function should actually be necessary. Should really just output a series of arrays, collecting each value into one array. // The caller can then run select on it and this means th the zipper function is unecessary. export type ZipNFn = (input: ISeries) => ReturnT; -export type Zip2Fn = (a: T1, b: T2) => ReturnT; +export type Zip2Fn = (a: T1, b : T2) => ReturnT; export type Zip3Fn = (a: T1, b: T2, c: T3) => ReturnT; export type Zip4Fn = (a: T1, b: T2, c: T3, d: T4) => ReturnT; export type Zip5Fn = (a: T1, b: T2, c: T3, d: T4) => ReturnT; @@ -133,7 +133,7 @@ export interface ITypeFrequency { /** * The name of the type. */ - Type: string; + Type: string; /** * The frequency of the type's appearance in the series or dataframe. @@ -149,7 +149,7 @@ export interface IValueFrequency { /** * The value. */ - Value: any; + Value: any; /** * The frequency of the value's appearance in the series or dataframe. @@ -182,7 +182,7 @@ export interface IBucket { * The mid-point value in the bucket. */ Mid: number; - + /** * The maximum value in the bucket. */ @@ -212,11 +212,11 @@ export interface IFrequencyTableOptions { */ upper?: number; - /** - * Directly sets the interval (if defined). This is the range of each group. - */ + /** + * Directly sets the interval (if defined). This is the range of each group. + */ interval?: number; - + /** * Enables capturing of values for each group. */ @@ -361,27 +361,27 @@ export interface ISeries extends Iterable */ resetIndex (): ISeries; - /** - * Merge one or more series into this series. - * Values are merged by index. - * Values at each index are combined into arrays in the resulting series. - * - * @param series... One or more other series to merge into the series. - * - * @returns The merged series. - * - * @example - *
-      * 
-      * const mergedSeries = series1.merge(series2);
-      * 
- * - *
-      * 
-      * const mergedSeries = series1.merge(series2, series3, etc);
-      * 
- */ - merge (...args: any[]): ISeries; + /** + * Merge one or more series into this series. + * Values are merged by index. + * Values at each index are combined into arrays in the resulting series. + * + * @param series... One or more other series to merge into the series. + * + * @returns The merged series. + * + * @example + *
+     * 
+     * const mergedSeries = series1.merge(series2);
+     * 
+ * + *
+     * 
+     * const mergedSeries = series1.merge(series2, series3, etc);
+     * 
+ */ + merge(...args: any[]): ISeries; /** * Extract values from the series as an array. @@ -394,7 +394,7 @@ export interface ISeries extends Iterable * const values = series.toArray(); * */ - toArray (options?: { includeNulls?: boolean }): ValueT[]; + toArray (options?: { includeNulls?: boolean }): ValueT[]; /** * Retreive the index, values pairs from the series as an array. @@ -408,7 +408,7 @@ export interface ISeries extends Iterable * const pairs = series.toPairs(); * */ - toPairs (): ([IndexT, ValueT])[]; + toPairs (): ([IndexT,ValueT])[]; /** * Convert the series to a JavaScript object. @@ -478,7 +478,7 @@ export interface ISeries extends Iterable * */ map (transformer: SelectorWithIndexFn): ISeries; - + /** * Transforms and flattens an input series, generating a new series. * The transformer function is called for each value in the input series and produces an array that is then flattened into the generated series. @@ -536,7 +536,7 @@ export interface ISeries extends Iterable * */ flatMap (transformer: SelectorWithIndexFn>): ISeries; - + /** * Partition a series into a {@link Series} of *data windows*. * Each value in the new series is a chunk of data from the original series. @@ -628,7 +628,7 @@ export interface ISeries extends Iterable * */ sequentialDistinct (selector: SelectorFn): ISeries; - + /** * Reduces the values in the series to a single result. * @@ -672,7 +672,7 @@ export interface ISeries extends Iterable * */ aggregate (seedOrSelector: AggregateFn | ToT, selector?: AggregateFn): ToT; - + /** * Reduces the values in the series to a single result. * @@ -885,7 +885,7 @@ export interface ISeries extends Iterable * @returns Returns a new series that is the cumulative sum of values across the input series. */ cumsum (): ISeries; - + /** * Skip a number of values in the series. * @@ -930,7 +930,7 @@ export interface ISeries extends Iterable * */ skipUntil (predicate: PredicateFn): ISeries; - + /** * Take a number of values from the series. * @@ -945,7 +945,7 @@ export interface ISeries extends Iterable * */ take (numRows: number): ISeries; - + /** * Takes values from the series while a condition evaluates to true or truthy. * @@ -975,7 +975,7 @@ export interface ISeries extends Iterable * */ takeUntil (predicate: PredicateFn): ISeries; - + /** * Count the number of values in the seriese * @@ -988,7 +988,7 @@ export interface ISeries extends Iterable * */ count (): number; - + /** * Get the first value of the series. * @@ -1142,7 +1142,7 @@ export interface ISeries extends Iterable * */ all (predicate: PredicateFn): boolean; - + /** * Evaluates a predicate function for every value in the series to determine * if some condition is true/truthy for **any** of values in the series. @@ -1310,7 +1310,7 @@ export interface ISeries extends Iterable * // Get all values after the specified date. * const result = timeSeries.after(new Date(2016, 5, 4)); * - */ + */ after (indexValue: IndexT): ISeries; /** @@ -1523,7 +1523,7 @@ export interface ISeries extends Iterable * */ median (): number; - + /** * Get the mode of the values in the series. * The mode is the most frequent value in the series. @@ -1775,9 +1775,9 @@ export interface ISeries extends Iterable * } * } * - */ + */ groupSequentialBy (selector?: SelectorFn): ISeries>; - + /** * Concatenate multiple other series onto this series. * @@ -1815,8 +1815,8 @@ export interface ISeries extends Iterable * const otherSeries = [... array of series...]; * const concatenated = a.concat(otherSeries); * - */ - concat (...series: (ISeries[] | ISeries)[]): ISeries; + */ + concat (...series: (ISeries[]|ISeries)[]): ISeries; /** * Zip together multiple series to create a new series. @@ -1834,12 +1834,12 @@ export interface ISeries extends Iterable * const b = new Series([10, 20, 30]); * const zipped = a.zip(b (valueA, valueB) => valueA + valueB); * - */ - zip (s2: ISeries, zipper: Zip2Fn): ISeries; - zip (s2: ISeries, s3: ISeries, zipper: Zip3Fn): ISeries; - zip (s2: ISeries, s3: ISeries, s4: ISeries, zipper: Zip3Fn): ISeries; - zip (...args: any[]): ISeries; - + */ + zip (s2: ISeries, zipper: Zip2Fn ): ISeries; + zip (s2: ISeries, s3: ISeries, zipper: Zip3Fn ): ISeries; + zip (s2: ISeries, s3: ISeries, s4: ISeries, zipper: Zip3Fn ): ISeries; + zip (...args: any[]): ISeries; + /** * Sorts the series in ascending order by a value defined by the user-defined selector function. * @@ -1933,9 +1933,9 @@ export interface ISeries extends Iterable * */ union ( - other: ISeries, - selector?: SelectorFn): - ISeries; + other: ISeries, + selector?: SelectorFn): + ISeries; /** * Creates a new series by merging two input series. @@ -1968,12 +1968,12 @@ export interface ISeries extends Iterable * customerRecord => customerRecord.CustomerId * ); * - */ + */ intersection ( - inner: ISeries, + inner: ISeries, outerSelector?: SelectorFn, - innerSelector?: SelectorFn): - ISeries; + innerSelector?: SelectorFn): + ISeries; /** * Creates a new series by merging two input series. @@ -2005,49 +2005,49 @@ export interface ISeries extends Iterable * customerRecord => customerRecord.CustomerId * ); * - */ + */ except ( - inner: ISeries, + inner: ISeries, outerSelector?: SelectorFn, - innerSelector?: SelectorFn): - ISeries; - - /** - * Creates a new series by merging two input series. - * The resulting dataframe contains only those value that have matching keys in both input series. - * - * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series). - * @param outerKeySelector User-defined selector function that chooses the join key from the outer series. - * @param innerKeySelector User-defined selector function that chooses the join key from the inner series. - * @param resultSelector User-defined function that merges outer and inner values. - * - * @return Returns the new merged series. - * - * @example - *
-      * 
-      * // Join together two sets of customers to find those
-      * // that have bought both product A and product B.
-      * const customerWhoBoughtProductA = ...
-      * const customerWhoBoughtProductB = ...
-      * const customersWhoBoughtBothProductsDf = customerWhoBoughtProductA.join(
-      *          customerWhoBoughtProductB,
-      *          customerA => customerA.CustomerId, // Join key.
-      *          customerB => customerB.CustomerId, // Join key.
-      *          (customerA, customerB) => {
-      *              return {
-      *                  // ... merge the results ...
-      *              };
-      *          }
-      *      );
-      * 
- */ + innerSelector?: SelectorFn): + ISeries; + + /** + * Creates a new series by merging two input series. + * The resulting dataframe contains only those value that have matching keys in both input series. + * + * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series). + * @param outerKeySelector User-defined selector function that chooses the join key from the outer series. + * @param innerKeySelector User-defined selector function that chooses the join key from the inner series. + * @param resultSelector User-defined function that merges outer and inner values. + * + * @return Returns the new merged series. + * + * @example + *
+     * 
+     * // Join together two sets of customers to find those
+     * // that have bought both product A and product B.
+     * const customerWhoBoughtProductA = ...
+     * const customerWhoBoughtProductB = ...
+     * const customersWhoBoughtBothProductsDf = customerWhoBoughtProductA.join(
+     *          customerWhoBoughtProductB,
+     *          customerA => customerA.CustomerId, // Join key.
+     *          customerB => customerB.CustomerId, // Join key.
+     *          (customerA, customerB) => {
+     *              return {
+     *                  // ... merge the results ...
+     *              };
+     *          }
+     *      );
+     * 
+ */ join ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries; + ISeries; /** * Creates a new series by merging two input series. @@ -2082,13 +2082,13 @@ export interface ISeries extends Iterable * } * ); * - */ + */ joinOuter ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries; + ISeries; /** * Creates a new series by merging two input series. @@ -2125,11 +2125,11 @@ export interface ISeries extends Iterable * */ joinOuterLeft ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries; + ISeries; /** * Creates a new series by merging two input series. @@ -2166,11 +2166,11 @@ export interface ISeries extends Iterable * */ joinOuterRight ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries; + ISeries; /** * Produces a new series with all string values truncated to the requested maximum length. @@ -2249,8 +2249,8 @@ export interface ISeries extends Iterable /** * Removes values from the series by index. */ - remove (index: IndexT): ISeries; - + remove(index: IndexT): ISeries; + /** * Fill gaps in a series. * @@ -2357,7 +2357,7 @@ export interface ISeries extends Iterable * console.log(buckets.toString()); * */ - bucket (numBuckets: number): IDataFrame; + bucket (numBuckets: number): IDataFrame; /** * Counts frequencies in the series to produce a frequency table. @@ -2453,7 +2453,7 @@ interface ISeriesContent { * Set to true when the dataframe has been baked into memory * and does not need to be lazily evaluated. */ - isBaked: boolean; + isBaked: boolean; } /** @@ -2483,14 +2483,14 @@ export class Series implements ISeries (iterator: Iterator): ISeriesContent { + private static initFromIterator(iterator: Iterator): ISeriesContent { return Series.initFromIterable(new CachedIteratorIterable(iterator)); } // // Initialise series content from an iterable of values. // - private static initFromIterable (arr: Iterable): ISeriesContent { + private static initFromIterable(arr: Iterable): ISeriesContent { return { index: Series.defaultCountIterable, values: arr, @@ -2502,7 +2502,7 @@ export class Series implements ISeries (): ISeriesContent { + private static initEmpty(): ISeriesContent { return { index: Series.defaultEmptyIterable, values: Series.defaultEmptyIterable, @@ -2514,22 +2514,22 @@ export class Series implements ISeries (input: any, fieldName: string): void { + private static checkIterable(input: any, fieldName: string): void { if (Series.isIterable(input)) { // Assume it's an iterable. // Ok @@ -2543,7 +2543,7 @@ export class Series implements ISeries (config: ISeriesConfig): ISeriesContent { + private static initFromConfig(config: ISeriesConfig): ISeriesContent { let index: Iterable; let values: Iterable; @@ -2681,7 +2681,7 @@ export class Series implements ISeries implements ISeries { + private getContent(): ISeriesContent { this.lazyInit(); return this.content!; } @@ -2698,14 +2698,14 @@ export class Series implements ISeries(); for (const pair of this.getContent().pairs) { this.indexedContent.set(pair[0], pair[1]); } } - + return this.indexedContent.get(index); } @@ -2724,7 +2724,7 @@ export class Series implements ISeries */ - [Symbol.iterator] (): Iterator { + [Symbol.iterator](): Iterator { return this.getContent().values[Symbol.iterator](); } @@ -2743,7 +2743,7 @@ export class Series implements ISeries (): ISeries { return this as any as ISeries; } - + /** * Get the index for the series. * @@ -2800,7 +2800,7 @@ export class Series implements ISeries, 'newIndex'); - + return new Series(() => ({ values: this.getContent().values, index: newIndex as Iterable, @@ -2840,9 +2840,9 @@ export class Series implements ISeries */ - static merge (series: Iterable>): ISeries { + static merge(series: Iterable>): ISeries { - const rowMap = new Map(); + const rowMap = new Map(); const numSeries = Array.from(series).length; //TODO: Be nice not to have to do this. let seriesIndex = 0; for (const workingSeries of series) { @@ -2878,30 +2878,30 @@ export class Series implements ISeries - * - * const mergedSeries = series1.merge(series2); - * - * - *
-      * 
-      * const mergedSeries = series1.merge(series2, series3, etc);
-      * 
- */ - merge (...args: any[]): ISeries { + /** + * Merge one or more series into this series. + * Values are merged by index. + * Values at each index are combined into arrays in the resulting series. + * + * @param series... One or more other series to merge into the series. + * + * @returns The merged series. + * + * @example + *
+     * 
+     * const mergedSeries = series1.merge(series2);
+     * 
+ * + *
+     * 
+     * const mergedSeries = series1.merge(series2, series3, etc);
+     * 
+ */ + merge(...args: any[]): ISeries { return Series.merge([this].concat(args)); } - + /** * Extract values from the series as an array. * This forces lazy evaluation to complete. @@ -2913,7 +2913,7 @@ export class Series implements ISeries */ - toArray (options?: { includeNulls?: boolean }): any[] { + toArray (options?: { includeNulls?: boolean }): any[] { const values = []; for (const value of this.getContent().values) { if (options && options.includeNulls && value !== undefined) { @@ -2971,7 +2971,7 @@ export class Series implements ISeries implements ISeries */ - select (transformer: SelectorWithIndexFn): ISeries { + select (transformer: SelectorWithIndexFn): ISeries { if (!isFunction(transformer)) throw new Error("Expected 'transformer' parameter to 'Series.select' to be a function."); return this.map(transformer); @@ -3024,7 +3024,7 @@ export class Series implements ISeries */ - map (transformer: SelectorWithIndexFn): ISeries { + map (transformer: SelectorWithIndexFn): ISeries { if (!isFunction(transformer)) throw new Error("Expected 'transformer' parameter to 'Series.map' to be a function."); return new Series(() => { @@ -3101,7 +3101,7 @@ export class Series implements ISeries ({ pairs: new SelectManyIterable( - this.getContent().pairs, + this.getContent().pairs, (pair: [IndexT, ValueT], index: number): Iterable<[IndexT, ToT]> => { const outputPairs: [IndexT, ToT][] = []; for (const transformed of transformer(pair[1], index)) { @@ -3200,7 +3200,7 @@ export class Series implements ISeries): ISeries> { - + if (!isFunction(comparer)) throw new Error("Expected 'comparer' parameter to 'Series.variableWindow' to be a function.") return new Series>(() => ({ @@ -3228,17 +3228,17 @@ export class Series implements ISeries */ sequentialDistinct (selector?: SelectorFn): ISeries { - + if (selector) { if (!isFunction(selector)) throw new Error("Expected 'selector' parameter to 'Series.sequentialDistinct' to be a selector function that determines the value to compare for duplicates.") } else { - selector = (value: ValueT): ToT => value; + selector = (value: ValueT): ToT => value; } return this.variableWindow((a, b) => selector!(a) === selector!(b)) .select((window): [IndexT, ValueT] => { - return [window.getIndex().first(), window.first()]; + return [window.getIndex().first(), window.first()] ; }) .withIndex(pair => pair[0]) .select(pair => pair[1]); @@ -3289,12 +3289,12 @@ export class Series implements ISeries (seedOrSelector: AggregateFn | ToT, selector?: AggregateFn): ToT { if (isFunction(seedOrSelector) && !selector) { - return this.skip(1).aggregate(this.first(), seedOrSelector); + return this.skip(1).aggregate( this.first(), seedOrSelector); } else { if (!isFunction(selector)) throw new Error("Expected 'selector' parameter to aggregate to be a function."); - let accum = seedOrSelector; + let accum = seedOrSelector; for (const value of this) { accum = selector!(accum, value); @@ -3303,7 +3303,7 @@ export class Series implements ISeries implements ISeries (reducer: AggregateFn, seed?: ToT): ToT { if (!isFunction(reducer)) throw new Error("Expected 'reducer' parameter to `Series.reduce` to be a function."); - let accum = seed; + let accum = seed; let series: ISeries = this; if (accum === undefined) { if (series.any()) { @@ -3370,10 +3370,10 @@ export class Series implements ISeries */ amountRange (period: number, whichIndex?: WhichIndex): ISeries { - return (>this) // Have to assume this is a number series. + return (> this) // Have to assume this is a number series. .rollingWindow(period, whichIndex) .select(window => window.max() - window.min()); - } + } /** * Compute the range of values in each period in proportion to the latest value. @@ -3394,10 +3394,10 @@ export class Series implements ISeries */ proportionRange (period: number, whichIndex?: WhichIndex): ISeries { - return (>this) // Have to assume this is a number series. + return (> this) // Have to assume this is a number series. .rollingWindow(period, whichIndex) .select(window => (window.max() - window.min()) / window.last()); - } + } /** * Compute the range of values in each period in proportion to the latest value. @@ -3442,10 +3442,10 @@ export class Series implements ISeries */ amountChange (period?: number, whichIndex?: WhichIndex): ISeries { - return (>this) // Have to assume this is a number series. + return (> this) // Have to assume this is a number series. .rollingWindow(period === undefined ? 2 : period, whichIndex) .select(window => window.last() - window.first()); - } + } /** * Compute the proportion change between pairs or sets of values in the series. @@ -3469,10 +3469,10 @@ export class Series implements ISeries */ proportionChange (period?: number, whichIndex?: WhichIndex): ISeries { - return (>this) // Have to assume this is a number series. + return (> this) // Have to assume this is a number series. .rollingWindow(period === undefined ? 2 : period, whichIndex) - .select(window => (window.last() - window.first()) / window.first()); - } + .select(window => (window.last() - window.first()) / window.first()); + } /** * Compute the percentage change between pairs or sets of values in the series. @@ -3497,8 +3497,8 @@ export class Series implements ISeries { return this.proportionChange(period, whichIndex).select(v => v * 100); - } - + } + /** * For each period, compute the proportion of values that are less than the last value in the period. * Proportions are expressed as 0-1 values. @@ -3526,8 +3526,8 @@ export class Series implements ISeries { const latestValue = window.last(); const numLowerValues = window.head(-1).filter(prevMomentum => prevMomentum < latestValue).count(); @@ -3563,7 +3563,7 @@ export class Series implements ISeries proportion * 100); } @@ -3601,7 +3601,7 @@ export class Series implements ISeries implements ISeries): ISeries { if (!isFunction(predicate)) throw new Error("Expected 'predicate' parameter to 'Series.skipUntil' function to be a predicate function that returns true/false."); - return this.skipWhile(value => !predicate(value)); + return this.skipWhile(value => !predicate(value)); } /** @@ -3725,7 +3725,7 @@ export class Series implements ISeries (series: ISeries): number { return series.count(); } - + /** * Count the number of values in the series. * @@ -3790,8 +3790,8 @@ export class Series implements ISeries implements ISeries implements ISeries { return new Series(() => { const lessThan = this.getIndex().getLessThan(); - return { + return { index: new SkipWhileIterable(this.getContent().index, index => lessThan(index, indexValue)), pairs: new SkipWhileIterable(this.getContent().pairs, pair => lessThan(pair[0], indexValue)), } @@ -4216,7 +4216,7 @@ export class Series implements ISeries - */ + */ after (indexValue: IndexT): ISeries { return new Series(() => { const lessThanOrEqualTo = this.getIndex().getLessThanOrEqualTo(); @@ -4257,7 +4257,7 @@ export class Series implements ISeries */ between (startIndexValue: IndexT, endIndexValue: IndexT): ISeries { - return this.startAt(startIndexValue).endAt(endIndexValue); + return this.startAt(startIndexValue).endAt(endIndexValue); } /** @@ -4299,7 +4299,7 @@ export class Series implements ISeries implements ISeries */ parseInts (): ISeries { - return >this.select(Series.parseInt); + return > this.select(Series.parseInt); } // @@ -4333,7 +4333,7 @@ export class Series implements ISeries implements ISeries */ parseFloats (): ISeries { - return >this.select(Series.parseFloat); + return > this.select(Series.parseFloat); } // @@ -4366,7 +4366,7 @@ export class Series implements ISeries implements ISeries>this.select((value: any | undefined, valueIndex: number) => Series.parseDate(value, valueIndex, formatString)); + return > this.select((value: any | undefined, valueIndex: number) => Series.parseDate(value, valueIndex, formatString)); } // // Helper function to convert a value to a string. // - static toString (value: any | undefined | null, formatString?: string): string | undefined | null { + static toString(value: any | undefined | null, formatString?: string): string | undefined | null { if (value === undefined) { return undefined; } @@ -4418,8 +4418,8 @@ export class Series implements ISeries implements ISeries>this.select(value => Series.toString(value, formatString)); + return > this.select(value => Series.toString(value, formatString)); } /** @@ -4524,9 +4524,9 @@ export class Series implements ISeries(() => { const content = this.getContent(); return { - values: >content.values, + values: > content.values, index: content.index, - pairs: >content.pairs, + pairs: > content.pairs, }; }); } @@ -4536,14 +4536,14 @@ export class Series implements ISeries { + private asNumberSeries(): ISeries { // // From here: http://stackoverflow.com/questions/5275115/add-a-median-method-to-a-list // // Have to assume we are working with a number series here. - const numberSeries = >this.filter(value => value !== null && value !== undefined); + const numberSeries = > this.filter(value => value !== null && value !== undefined); - if (numberSeries.any(value => typeof (value) !== "number")) { + if (numberSeries.any(value => typeof(value) !== "number")) { throw new Error(`Expected series to contain only numbers, you should parse this series or filter out non-number values.`); } @@ -4614,7 +4614,7 @@ export class Series implements ISeries (series: ISeries): number { return series.average(); } - + /** * Average the values in a series and returns the result * @@ -4650,7 +4650,7 @@ export class Series implements ISeries (series: ISeries): number { return series.mean(); } - + /** * Computes and returns the mean value of a set of values. * @@ -4662,7 +4662,7 @@ export class Series implements ISeries */ - mean (): number { + mean (): number { const numberSeries = this.asNumberSeries(); if (numberSeries.none()) { @@ -4682,7 +4682,7 @@ export class Series implements ISeries implements ISeries implements ISeries(); for (const value of numberSeries) { - if (lookup.has(value)) { + if (lookup.has(value)) { lookup.set(value, lookup.get(value)! + 1); } else { @@ -4802,7 +4802,7 @@ export class Series implements ISeries implements ISeries */ - static variance (series: ISeries): number { + static variance (series: ISeries): number { return series.variance(); } - + /** * Get the (population) variance of number values in the series. * @@ -4845,7 +4845,7 @@ export class Series implements ISeries */ - variance (): number { + variance (): number { if (this.none()) { return 0; @@ -4873,7 +4873,7 @@ export class Series implements ISeries (series: ISeries): number { return series.std(); } - + /** * Get the (population) standard deviation of number values in the series. * @@ -4907,7 +4907,7 @@ export class Series implements ISeries */ standardize (): ISeries { - + if (this.none()) { // There are no values in the input series. return new Series(); @@ -4941,10 +4941,10 @@ export class Series implements ISeries */ - static sampleVariance (series: ISeries): number { + static sampleVariance (series: ISeries): number { return series.sampleVariance(); } - + /** * Get the (sample) variance of number values in the series. * @@ -4956,7 +4956,7 @@ export class Series implements ISeries */ - sampleVariance (): number { + sampleVariance (): number { if (this.none()) { return 0; @@ -4984,7 +4984,7 @@ export class Series implements ISeries (series: ISeries): number { return series.sampleStd(); } - + /** * Get the (sample) standard deviation of number values in the series. * @@ -5018,7 +5018,7 @@ export class Series implements ISeries */ sampleStandardize (): ISeries { - + if (this.none()) { // There are no values in the input series. return new Series(); @@ -5105,7 +5105,7 @@ export class Series implements ISeries (series: ISeries): number { return series.max(); } - + /** * Get the max value in the series. * @@ -5155,7 +5155,7 @@ export class Series implements ISeries (series: ISeries): number { return series.range(); } - + /** * Get the range of values in the series. * @@ -5170,7 +5170,7 @@ export class Series implements ISeries implements ISeries { return -value; - }); + }); } /** @@ -5222,11 +5222,11 @@ export class Series implements ISeries pair[0]) .select(pair => pair[1]) as any as ISeries; } - + /** * Gets a new series in reverse order. * @@ -5272,7 +5272,7 @@ export class Series implements ISeries(() => ({ values: new DistinctIterable(this.getContent().values, selector), - pairs: new DistinctIterable<[IndexT, ValueT], ToT>(this.getContent().pairs, (pair: [IndexT, ValueT]): ToT => selector && selector(pair[1]) || pair[1]) + pairs: new DistinctIterable<[IndexT, ValueT],ToT>(this.getContent().pairs, (pair: [IndexT, ValueT]): ToT => selector && selector(pair[1]) || pair[1]) })); } @@ -5303,9 +5303,9 @@ export class Series implements ISeries>(() => { const groups: any[] = []; // Each group, in order of discovery. const groupMap: any = {}; // Group map, records groups by key. - + let valueIndex = 0; - + for (const pair of this.getContent().pairs) { const groupKey = selector(pair[1], valueIndex); ++valueIndex; @@ -5323,10 +5323,10 @@ export class Series implements ISeries new Series({ pairs: group })) - }; + }; }); } - + /** * Collects values in the series into a new series of groups based on if the values are the same or according to a user-defined selector function. * @@ -5354,16 +5354,16 @@ export class Series implements ISeries - */ + */ groupSequentialBy (selector?: SelectorFn): ISeries> { if (selector) { if (!isFunction(selector)) throw new Error("Expected 'selector' parameter to 'Series.groupSequentialBy' to be a selector function that determines the value to group the series by.") } else { - selector = value => value; + selector = value => value; } - + return this.variableWindow((a: ValueT, b: ValueT): boolean => selector!(a) === selector!(b)); } @@ -5378,7 +5378,7 @@ export class Series implements ISeries { - const upcast = []>series; // Upcast so that we can access private index, values and pairs. + const upcast = []> series; // Upcast so that we can access private index, values and pairs. const contents = upcast.map(series => series.getContent()); return { values: new ConcatIterable(contents.map(content => content.values)), @@ -5386,7 +5386,7 @@ export class Series implements ISeries implements ISeries - */ - concat (...series: (ISeries[] | ISeries)[]): ISeries { + */ + concat (...series: (ISeries[]|ISeries)[]): ISeries { const concatInput: ISeries[] = [this]; for (const input of series) { @@ -5441,7 +5441,7 @@ export class Series implements ISeries(concatInput); } - + /** * Zip together multiple series to create a new series. * Preserves the index of the first series. @@ -5465,16 +5465,16 @@ export class Series implements ISeries(() => { - const firstSeriesUpCast = >firstSeries; - const upcast = []>input; // Upcast so that we can access private index, values and pairs. - + const firstSeriesUpCast = > firstSeries; + const upcast = []> input; // Upcast so that we can access private index, values and pairs. + return { - index: >firstSeriesUpCast.getContent().index, + index: > firstSeriesUpCast.getContent().index, values: new ZipIterable(upcast.map(s => s.getContent().values), zipper), }; }); } - + /** * Merge together multiple series to create a new series. * Preserves the index of the first series. @@ -5491,16 +5491,16 @@ export class Series implements ISeries valueA + valueB); * - */ - zip (s2: ISeries, zipper: Zip2Fn): ISeries; - zip (s2: ISeries, s3: ISeries, zipper: Zip3Fn): ISeries; - zip (s2: ISeries, s3: ISeries, s4: ISeries, zipper: Zip3Fn): ISeries; - zip (...args: any[]): ISeries { - - const selector: Function = args[args.length - 1]; - const input: ISeries[] = [this].concat(args.slice(0, args.length - 1)); + */ + zip (s2: ISeries, zipper: Zip2Fn ): ISeries; + zip (s2: ISeries, s3: ISeries, zipper: Zip3Fn ): ISeries; + zip (s2: ISeries, s3: ISeries, s4: ISeries, zipper: Zip3Fn ): ISeries; + zip (...args: any[]): ISeries { + + const selector: Function = args[args.length-1]; + const input: ISeries[] = [this].concat(args.slice(0, args.length-1)); return Series.zip(input, values => selector(...values)); - } + } /** * Sorts the series in ascending order by a value defined by the user-defined selector function. @@ -5524,10 +5524,10 @@ export class Series implements ISeries (selector: SelectorWithIndexFn): IOrderedSeries { const content = this.getContent(); return new OrderedSeries({ - values: content.values, - pairs: content.pairs, - selector: selector, - direction: Direction.Ascending, + values: content.values, + pairs: content.pairs, + selector: selector, + direction: Direction.Ascending, parent: null, }); } @@ -5554,14 +5554,14 @@ export class Series implements ISeries (selector: SelectorWithIndexFn): IOrderedSeries { const content = this.getContent(); return new OrderedSeries({ - values: content.values, - pairs: content.pairs, - selector: selector, - direction: Direction.Descending, + values: content.values, + pairs: content.pairs, + selector: selector, + direction: Direction.Descending, parent: null, }); } - + /** * Creates a new series by merging two input dataframes. * The resulting series contains the union of value from the two input series. @@ -5613,9 +5613,9 @@ export class Series implements ISeries ( - other: ISeries, - selector?: SelectorFn): - ISeries { + other: ISeries, + selector?: SelectorFn): + ISeries { if (selector) { if (!isFunction(selector)) throw new Error("Expected optional 'selector' parameter to 'Series.union' to be a selector function."); @@ -5655,34 +5655,34 @@ export class Series implements ISeries customerRecord.CustomerId * ); * - */ + */ intersection ( - inner: ISeries, + inner: ISeries, outerSelector?: SelectorFn, - innerSelector?: SelectorFn): - ISeries { + innerSelector?: SelectorFn): + ISeries { if (outerSelector) { if (!isFunction(outerSelector)) throw new Error("Expected optional 'outerSelector' parameter to 'Series.intersection' to be a function."); } else { - outerSelector = value => value; + outerSelector = value => value; } - + if (innerSelector) { if (!isFunction(innerSelector)) throw new Error("Expected optional 'innerSelector' parameter to 'Series.intersection' to be a function."); } else { - innerSelector = value => value; + innerSelector = value => value; } const outer = this; return outer.filter(outerValue => { - const outerKey = outerSelector!(outerValue); - return inner - .filter(innerValue => outerKey === innerSelector!(innerValue)) - .any(); - }); + const outerKey = outerSelector!(outerValue); + return inner + .filter(innerValue => outerKey === innerSelector!(innerValue)) + .any(); + }); } /** @@ -5715,72 +5715,72 @@ export class Series implements ISeries customerRecord.CustomerId * ); * - */ + */ except ( - inner: ISeries, + inner: ISeries, outerSelector?: SelectorFn, - innerSelector?: SelectorFn): - ISeries { + innerSelector?: SelectorFn): + ISeries { if (outerSelector) { if (!isFunction(outerSelector)) throw new Error("Expected optional 'outerSelector' parameter to 'Series.except' to be a function."); } else { - outerSelector = value => value; + outerSelector = value => value; } if (innerSelector) { if (!isFunction(innerSelector)) throw new Error("Expected optional 'innerSelector' parameter to 'Series.except' to be a function."); } else { - innerSelector = value => value; + innerSelector = value => value; } const outer = this; return outer.filter(outerValue => { - const outerKey = outerSelector!(outerValue); - return inner - .filter(innerValue => outerKey === innerSelector!(innerValue)) - .none(); - }); + const outerKey = outerSelector!(outerValue); + return inner + .filter(innerValue => outerKey === innerSelector!(innerValue)) + .none(); + }); } - /** - * Creates a new series by merging two input series. - * The resulting dataframe contains only those value that have matching keys in both input series. - * - * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series). - * @param outerKeySelector User-defined selector function that chooses the join key from the outer series. - * @param innerKeySelector User-defined selector function that chooses the join key from the inner series. - * @param resultSelector User-defined function that merges outer and inner values. - * - * @return Returns the new merged series. - * - * @example - *
-      * 
-      * // Join together two sets of customers to find those
-      * // that have bought both product A and product B.
-      * const customerWhoBoughtProductA = ...
-      * const customerWhoBoughtProductB = ...
-      * const customersWhoBoughtBothProductsDf = customerWhoBoughtProductA.join(
-      *          customerWhoBoughtProductB,
-      *          customerA => customerA.CustomerId, // Join key.
-      *          customerB => customerB.CustomerId, // Join key.
-      *          (customerA, customerB) => {
-      *              return {
-      *                  // ... merge the results ...
-      *              };
-      *          }
-      *      );
-      * 
- */ + /** + * Creates a new series by merging two input series. + * The resulting dataframe contains only those value that have matching keys in both input series. + * + * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series). + * @param outerKeySelector User-defined selector function that chooses the join key from the outer series. + * @param innerKeySelector User-defined selector function that chooses the join key from the inner series. + * @param resultSelector User-defined function that merges outer and inner values. + * + * @return Returns the new merged series. + * + * @example + *
+     * 
+     * // Join together two sets of customers to find those
+     * // that have bought both product A and product B.
+     * const customerWhoBoughtProductA = ...
+     * const customerWhoBoughtProductB = ...
+     * const customersWhoBoughtBothProductsDf = customerWhoBoughtProductA.join(
+     *          customerWhoBoughtProductB,
+     *          customerA => customerA.CustomerId, // Join key.
+     *          customerB => customerB.CustomerId, // Join key.
+     *          (customerA, customerB) => {
+     *              return {
+     *                  // ... merge the results ...
+     *              };
+     *          }
+     *      );
+     * 
+ */ join ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries { + ISeries { if (!isFunction(outerKeySelector)) throw new Error("Expected 'outerKeySelector' parameter of 'Series.join' to be a selector function."); if (!isFunction(innerKeySelector)) throw new Error("Expected 'innerKeySelector' parameter of 'Series.join' to be a selector function."); @@ -5792,21 +5792,21 @@ export class Series implements ISeries innerKeySelector(group.first()), + group => innerKeySelector(group.first()), group => group ); const outerContent = outer.getContent(); const output: ResultValueT[] = []; - + for (const outerValue of outer) { //TODO: There should be an enumerator that does this. const outerKey = outerKeySelector(outerValue); const innerGroup = innerMap[outerKey]; if (innerGroup) { for (const innerValue of innerGroup) { output.push(resultSelector(outerValue, innerValue)); - } + } } } @@ -5849,13 +5849,13 @@ export class Series implements ISeries - */ + */ joinOuter ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries { + ISeries { if (!isFunction(outerKeySelector)) throw new Error("Expected 'outerKeySelector' parameter of 'Series.joinOuter' to be a selector function."); if (!isFunction(innerKeySelector)) throw new Error("Expected 'innerKeySelector' parameter of 'Series.joinOuter' to be a selector function."); @@ -5916,11 +5916,11 @@ export class Series implements ISeries */ joinOuterLeft ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries { + ISeries { if (!isFunction(outerKeySelector)) throw new Error("Expected 'outerKeySelector' parameter of 'Series.joinOuterLeft' to be a selector function."); if (!isFunction(innerKeySelector)) throw new Error("Expected 'innerKeySelector' parameter of 'Series.joinOuterLeft' to be a selector function."); @@ -5975,11 +5975,11 @@ export class Series implements ISeries */ joinOuterRight ( - inner: ISeries, - outerKeySelector: SelectorFn, - innerKeySelector: SelectorFn, + inner: ISeries, + outerKeySelector: SelectorFn, + innerKeySelector: SelectorFn, resultSelector: JoinFn): - ISeries { + ISeries { if (!isFunction(outerKeySelector)) throw new Error("Expected 'outerKeySelector' parameter of 'Series.joinOuterRight' to be a selector function."); if (!isFunction(innerKeySelector)) throw new Error("Expected 'innerKeySelector' parameter of 'Series.joinOuterRight' to be a selector function."); @@ -5997,7 +5997,7 @@ export class Series implements ISeries implements ISeries { if (isNumber(value)) { return parseFloat(value.toFixed(numDecimalPlaces)); @@ -6119,7 +6119,7 @@ export class Series implements ISeries { + remove(index: IndexT): ISeries { return new Series(() => { const content = this.getContent(); @@ -6175,7 +6175,7 @@ export class Series implements ISeries implements ISeries>defaultSequence; + return > defaultSequence; } else if (isArray(defaultSequence)) { return new Series(defaultSequence); @@ -6219,7 +6219,7 @@ export class Series implements ISeries implements ISeries { - let valueType: string = typeof (value); - if (valueType === "object") { - if (isDate(value)) { - valueType = "date"; + let valueType: string = typeof(value); + if (valueType === "object") { + if (isDate(value)) { + valueType = "date"; + } } - } - return valueType; - }) + return valueType; + }) .aggregate({}, (accumulated: any, valueType: string) => { var typeInfo = accumulated[valueType]; if (!typeInfo) { @@ -6354,18 +6354,18 @@ export class Series implements ISeries { - var bucket = Math.floor((v - min) / width); - var bucketMin = (bucket * width) + min; - return { - Value: v, - Bucket: bucket, - Min: bucketMin, - Mid: bucketMin + (width * 0.5), - Max: bucketMin + width, - }; - }) + var bucket = Math.floor((v - min) / width); + var bucketMin = (bucket * width) + min; + return { + Value: v, + Bucket: bucket, + Min: bucketMin, + Mid: bucketMin + (width*0.5), + Max: bucketMin + width, + }; + }) .inflate(); } @@ -6448,13 +6448,13 @@ export class Series implements ISeries(numGroups); @@ -6468,7 +6468,7 @@ export class Series implements ISeries implements ISeries implements ISeries implements ISeries implements ISeries { * @hidden * A series that has been ordered. */ -class OrderedSeries +class OrderedSeries extends Series implements IOrderedSeries { @@ -6662,10 +6662,10 @@ class OrderedSeries */ thenBy (selector: SelectorWithIndexFn): IOrderedSeries { return new OrderedSeries({ - values: this.config.values, - pairs: this.config.pairs, - selector: selector, - direction: Direction.Ascending, + values: this.config.values, + pairs: this.config.pairs, + selector: selector, + direction: Direction.Ascending, parent: this, }); } @@ -6687,10 +6687,10 @@ class OrderedSeries thenByDescending (selector: SelectorWithIndexFn): IOrderedSeries { return new OrderedSeries({ values: this.config.values, - pairs: this.config.pairs, - selector: selector, - direction: Direction.Descending, + pairs: this.config.pairs, + selector: selector, + direction: Direction.Descending, parent: this }); } -} +} \ No newline at end of file