typescript
35 lines · 6 steps
Streaming running averages in TypeScript
Two takes on incremental aggregation: a stateful class and a lazy generator that emit stats one value at a time.
Explained by
highlit
1interface RunningStats {
2 count: number;
3 total: number;
4 average: number;
5}
6
7class RunningAggregator {
8 private count = 0;
9 private total = 0;
10
11 push(value: number): RunningStats {
12 this.count += 1;
13 this.total += value;
14 return this.snapshot();
15 }
16
17 snapshot(): RunningStats {
18 return {
19 count: this.count,
20 total: this.total,
21 average: this.count === 0 ? 0 : this.total / this.count,
22 };
23 }
24}
25
26function* runningStats(source: Iterable<number>): Generator<RunningStats> {
27 let count = 0;
28 let total = 0;
29
30 for (const value of source) {
31 count += 1;
32 total += value;
33 yield { count, total, average: total / count };
34 }
35}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Maintaining a running count and total lets you compute an average in O(1) per value without rescanning history.
- 2A class holds state across separate calls, while a generator threads state through a single lazy iteration.
- 3Returning an immutable snapshot object keeps internal accumulators private and safe from outside mutation.
Related explainers
typescript
type RGB = { r: number; g: number; b: number }; function parseHex(hex: string): RGB { const normalized = hex.replace(/^#/, "").trim();
Lightening and darkening hex colors in TypeScript
bitwise
color-manipulation
parsing
Intermediate
9 steps
rust
use axum::{ body::Body, extract::State, http::{header, StatusCode},
Streaming a DB migration with Axum
streaming
keyset-pagination
backpressure
Advanced
8 steps
python
import heapq class MovingMedian:
Running median with two heaps
heaps
streaming
invariants
Advanced
8 steps
typescript
import { IsEmail, IsNotEmpty, IsOptional,
How validation groups reuse one DTO in NestJS
validation
dto
decorators
Intermediate
9 steps
typescript
import { InjectionToken, inject, Provider, isDevMode } from '@angular/core'; import { WINDOW } from './window.token'; export interface AnalyticsConfig {
Layered config with an Angular InjectionToken
dependency-injection
configuration
factory-provider
Intermediate
8 steps
typescript
import { useCallback, useRef, useState } from "react"; type UploadZoneProps = { accept?: string[];
A drag-and-drop file upload zone in React
drag-and-drop
file-validation
controlled-state
Intermediate
9 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/streaming-running-averages-in-typescript-explained-typescript-582d/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.