{"id":31744952,"url":"https://github.com/yefremov/aggregatejs","last_synced_at":"2026-05-15T08:40:08.532Z","repository":{"id":57174496,"uuid":"82286310","full_name":"yefremov/aggregatejs","owner":"yefremov","description":"Aggregate functions returning single result based on groups of data","archived":false,"fork":false,"pushed_at":"2017-04-27T19:39:45.000Z","size":15,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-18T08:59:26.605Z","etag":null,"topics":["aggregate","browser","functions","nodejs","utilities"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yefremov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-17T10:33:05.000Z","updated_at":"2023-03-07T08:33:33.000Z","dependencies_parsed_at":"2022-08-28T21:00:23.358Z","dependency_job_id":null,"html_url":"https://github.com/yefremov/aggregatejs","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/yefremov/aggregatejs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yefremov%2Faggregatejs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yefremov%2Faggregatejs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yefremov%2Faggregatejs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yefremov%2Faggregatejs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yefremov","download_url":"https://codeload.github.com/yefremov/aggregatejs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yefremov%2Faggregatejs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001445,"owners_count":26083078,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aggregate","browser","functions","nodejs","utilities"],"created_at":"2025-10-09T12:28:10.906Z","updated_at":"2026-05-15T08:40:08.526Z","avatar_url":"https://github.com/yefremov.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# aggregatejs [![codecov](https://codecov.io/gh/yefremov/aggregatejs/branch/master/graph/badge.svg?token=HWKSO2VZRJ)](https://codecov.io/gh/yefremov/aggregatejs) \n\nA comprehensive set of statistical and mathematical aggregation functions written in TypeScript.\n\n## Installation\n\n```bash\n$ npm install aggregatejs\n```\n\n## Example\n\n### TypeScript / ES6\n\n```typescript\nimport { max, min, mode, quartiles } from 'aggregatejs';\n// top-level exports can be imported individually (recommended)\nimport percentile from 'aggregatejs/dist/percentile';\nimport average from 'aggregatejs/dist/average';\n\nmax([100, -100, 150, -50, 250, 100]);\n// =\u003e 250\n\nmin([100, -100, 150, -50, 250, 100]);\n// =\u003e -100\n\nmode([1, 2, 2, 3, 4]);\n// =\u003e 2\n\nquartiles([1, 2, 3, 4, 5, 6, 7, 8, 9]);\n// =\u003e { q1: 3, q2: 5, q3: 7 }\n```\n\n### CommonJS\n\n```javascript\nconst { max, min, mode, quartiles } = require('aggregatejs');\nconst percentile = require('aggregatejs/dist/percentile').default;\nconst average = require('aggregatejs/dist/average').default;\n\nmax([100, -100, 150, -50, 250, 100]);\n// =\u003e 250\n\nmin([100, -100, 150, -50, 250, 100]);\n// =\u003e -100\n```\n\n## API\n\nAll aggregate functions expect an array of numbers and return computed values. **All functions throw errors for invalid input** (empty arrays, NaN, Infinity).\n\n### Basic Statistics\n\n#### average\n\nReturns the arithmetic mean of the numbers in `array`.\n\n```js\naverage([100, -100, 150, -50, 100, 250]);\n// =\u003e 75\n```\n\n**Throws:**\n- `RangeError` if array is empty\n- `TypeError` if array contains non-numeric or non-finite values\n\n#### count\n\nCounts the numbers in `array`.\n\n```js\ncount([100, -100, 150, -50, 100, 250]);\n// =\u003e 6\n```\n\n**Throws:**\n- `RangeError` if array is empty\n- `TypeError` if array contains non-numeric or non-finite values\n\n#### max\n\nReturns the largest number in `array`.\n\n```js\nmax([100, -100, 150, -50, 250, 100]);\n// =\u003e 250\n```\n\n**Throws:**\n- `RangeError` if array is empty\n- `TypeError` if array contains non-numeric or non-finite values\n\n#### min\n\nReturns the smallest number in `array`.\n\n```js\nmin([100, -100, 150, -50, 250, 100]);\n// =\u003e -100\n```\n\n**Throws:**\n- `RangeError` if array is empty\n- `TypeError` if array contains non-numeric or non-finite values\n\n#### sum\n\nReturns the sum of all numbers in `array`.\n\n```js\nsum([100, -100, 150, -50, 100, 250]);\n// =\u003e 450\n```\n\n**Throws:**\n- `RangeError` if array is empty\n- `TypeError` if array contains non-numeric or non-finite values\n\n#### range\n\nReturns the difference between the maximum and minimum values in `array`.\n\n```js\nrange([100, -100, 150, -50, 250, 100]);\n// =\u003e 350 (250 - (-100))\n```\n\n**Throws:**\n- `RangeError` if array is empty\n- `TypeError` if array contains non-numeric or non-finite values\n\n#### mode\n\nReturns the most frequently occurring value(s) in `array`. If multiple values have the same highest frequency, returns an array of all modes.\n\n```js\nmode([1, 2, 2, 3, 4]);\n// =\u003e 2\n\nmode([1, 1, 2, 2, 3]);\n// =\u003e [1, 2]\n```\n\n**Throws:**\n- `RangeError` if array is empty\n- `TypeError` if array contains non-numeric or non-finite values\n\n### Positional Statistics\n\n#### median\n\nReturns the median (middle value) of the numbers in `array`. Does not mutate the input array.\n\n```js\nmedian([100, -100, 150, -50, 100, 250]);\n// =\u003e 100\n```\n\n**Throws:**\n- `RangeError` if array is empty\n- `TypeError` if array contains non-numeric or non-finite values\n\n#### percentile\n\nReturns the `k`-th percentile of values in `array`, where `k` is between 0 and 1. Does not mutate the input array.\n\n```js\npercentile([100, -100, 150, -50, 100, 250], 0.25);\n// =\u003e -12.5\n\npercentile([100, -100, 150, -50, 100, 250], 0.50);\n// =\u003e 100\n\npercentile([100, -100, 150, -50, 100, 250], 0.95);\n// =\u003e 225\n```\n\n**Throws:**\n- `RangeError` if array is empty or k is outside [0, 1] range\n- `TypeError` if array contains non-numeric or non-finite values, or k is not a finite number\n\n#### quartiles\n\nReturns an object containing the first quartile (Q1), median (Q2), and third quartile (Q3) of the numbers in `array`.\n\n```js\nquartiles([1, 2, 3, 4, 5, 6, 7, 8, 9]);\n// =\u003e { q1: 3, q2: 5, q3: 7 }\n```\n\n**Throws:**\n- `RangeError` if array is empty\n- `TypeError` if array contains non-numeric or non-finite values\n\n### Dispersion Statistics\n\n#### variance\n\nReturns the population variance of the numbers in `array`.\n\n```js\nvariance([2, 4, 4, 4, 5, 5, 7, 9]);\n// =\u003e 4\n```\n\n**Throws:**\n- `RangeError` if array is empty\n- `TypeError` if array contains non-numeric or non-finite values\n\n#### deviation\n\nReturns the standard deviation of the numbers in `array`.\n\n```js\ndeviation([2, 4, 4, 4, 5, 5, 7, 9]);\n// =\u003e 2\n```\n\n**Throws:**\n- `RangeError` if array is empty\n- `TypeError` if array contains non-numeric or non-finite values\n\n### Correlation and Covariance\n\n#### correlation\n\nReturns the Pearson correlation coefficient between two arrays of numbers. The correlation measures the strength and direction of a linear relationship between two variables, ranging from -1 (perfect negative correlation) to 1 (perfect positive correlation). A value of 0 indicates no linear correlation.\n\n```js\ncorrelation([1, 2, 3, 4, 5], [2, 4, 6, 8, 10]);\n// =\u003e 1 (perfect positive correlation)\n\ncorrelation([1, 2, 3, 4, 5], [5, 4, 3, 2, 1]);\n// =\u003e -1 (perfect negative correlation)\n\ncorrelation([1, 2, 3, 4, 5], [1, 3, 2, 5, 4]);\n// =\u003e 0.1 (weak correlation)\n```\n\n**Throws:**\n- `RangeError` if arrays are empty, have different lengths, or contain only constant values (zero standard deviation)\n- `TypeError` if arrays contain non-numeric or non-finite values\n\n#### covariance\n\nReturns the population covariance between two arrays of numbers. Covariance measures how two variables change together. Positive values indicate that both variables tend to increase together, while negative values indicate an inverse relationship.\n\n```js\ncovariance([1, 2, 3, 4, 5], [2, 4, 6, 8, 10]);\n// =\u003e 4\n\ncovariance([1, 2, 3], [3, 2, 1]);\n// =\u003e -1\n```\n\n**Throws:**\n- `RangeError` if arrays are empty or have different lengths\n- `TypeError` if arrays contain non-numeric or non-finite values\n\n### Specialized Means\n\n#### geometricMean\n\nReturns the geometric mean of the numbers in `array`. The geometric mean is the nth root of the product of n numbers.\n\n```js\ngeometricMean([2, 8]);\n// =\u003e 4\n\ngeometricMean([1, 3, 9, 27, 81]);\n// =\u003e 9\n```\n\n**Throws:**\n- `RangeError` if array is empty or contains negative numbers\n- `TypeError` if array contains non-numeric or non-finite values\n\n**Note:** Returns 0 if any value in the array is 0.\n\n#### harmonicMean\n\nReturns the harmonic mean of the numbers in `array`. The harmonic mean is the reciprocal of the arithmetic mean of reciprocals.\n\n```js\nharmonicMean([1, 2, 4]);\n// =\u003e 1.7142857142857142\n\nharmonicMean([2, 3]);\n// =\u003e 2.4\n```\n\n**Throws:**\n- `RangeError` if array is empty or contains zero\n- `TypeError` if array contains non-numeric or non-finite values\n\n## Error Handling\n\nAll functions in v1.0.0+ provide robust error handling:\n\n- **Empty Arrays**: All functions throw `RangeError` with message \"Array cannot be empty\"\n- **Invalid Input**: All functions throw `TypeError` with descriptive messages for:\n  - Non-array inputs\n  - Arrays containing `NaN`\n  - Arrays containing `Infinity` or `-Infinity`\n  - Non-numeric values\n- **Invalid Parameters**: Functions like `percentile()` validate their parameters and throw appropriate errors\n\n### Example Error Handling\n\n```typescript\nimport { max } from 'aggregatejs';\n\ntry {\n  max([]);\n} catch (error) {\n  console.error(error); // RangeError: Array cannot be empty\n}\n\ntry {\n  max([1, NaN, 3]);\n} catch (error) {\n  console.error(error); // TypeError: All array elements must be finite numbers\n}\n```\n\n## Migration from v0.x to v1.0.0\n\nSee [CHANGELOG.md](CHANGELOG.md) for detailed migration instructions.\n\n**Key Breaking Changes:**\n- Empty arrays now throw errors instead of returning 0\n- Invalid input (NaN, Infinity) now throws errors\n- `median()` and `percentile()` no longer mutate input arrays\n\n## Development\n\n### Building\n\n```bash\n$ npm run build\n```\n\n### Running tests\n\n```bash\n$ npm test\n```\n\n### Running performance benchmarks\n\nPerformance tests help measure and track the execution speed of aggregation functions across different dataset sizes.\n\n```bash\n# Run all performance benchmarks\n$ npm run perf\n\n# Run specific benchmark suites\n$ npm run perf:basic          # Basic statistics (average, sum, min, max, count, range)\n$ npm run perf:positional     # Positional statistics (median, percentile, quartiles)\n$ npm run perf:specialized    # Specialized functions (mode, variance, deviation, geometric/harmonic means)\n```\n\n**Performance Test Coverage:**\n- **Small datasets** (10 elements) - Typical use cases\n- **Medium datasets** (1,000 elements) - Common real-world scenarios\n- **Large datasets** (100,000 elements) - Stress testing\n- **Extra large datasets** (1,000,000 elements) - Extreme performance testing\n\nThe benchmarks provide:\n- Operations per second (ops/sec)\n- Mean execution time\n- Margin of error\n- Sample size for statistical significance\n\n### Clean build artifacts\n\n```bash\n$ npm run clean\n```\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyefremov%2Faggregatejs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyefremov%2Faggregatejs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyefremov%2Faggregatejs/lists"}