Skip to content

Scan Method

The scan() method performs a running accumulation over the collection, returning a new collection containing all intermediate results. Similar to reduce, but preserves all steps of the accumulation process.

Basic Syntax

typescript
scan<U>(callback: (acc: U, item: T) => U, initial: U): CollectionOperations<U>

Examples

Basic Usage

typescript
import { collect } from 'ts-collect'

const numbers = collect([1, 2, 3, 4])
const runningSum = numbers.scan((acc, num) => acc + num, 0)

console.log(runningSum.all())
// [1, 3, 6, 10]
// Shows cumulative sum at each step

Working with Complex Values

typescript
interface Transaction {
  amount: number
  type: 'credit' | 'debit'
}

const transactions = collect<Transaction>([
  { amount: 100, type: 'credit' },
  { amount: 50, type: 'debit' },
  { amount: 75, type: 'credit' }
])

const balanceHistory = transactions.scan((balance, tx) => {
  return tx.type === 'credit'
    ? balance + tx.amount
    : balance - tx.amount
}, 0)

console.log(balanceHistory.all())
// [100, 50, 125]

Real-world Example: E-commerce Order Processing

typescript
interface Order {
  orderId: string
  amount: number
  items: number
  timestamp: Date
}

class OrderAnalyzer {
  private orders: Collection<Order>

  constructor(orders: Order[]) {
    this.orders = collect(orders)
  }

  getRunningMetrics() {
    return this.orders
      .sortBy('timestamp')
      .scan((metrics, order) => ({
        totalOrders: metrics.totalOrders + 1,
        totalRevenue: metrics.totalRevenue + order.amount,
        totalItems: metrics.totalItems + order.items,
        averageOrderValue: (metrics.totalRevenue + order.amount) / (metrics.totalOrders + 1),
        averageItemsPerOrder: (metrics.totalItems + order.items) / (metrics.totalOrders + 1)
      }), {
        totalOrders: 0,
        totalRevenue: 0,
        totalItems: 0,
        averageOrderValue: 0,
        averageItemsPerOrder: 0
      })
  }

  getRevenueCheckpoints(): Collection<{
    checkpoint: number
    ordersNeeded: number
    timestamp: Date
  }> {
    const target = 10000 // $10,000 checkpoints

    return this.orders
      .sortBy('timestamp')
      .scan((acc, order) => ({
        total: acc.total + order.amount,
        ordersProcessed: acc.ordersProcessed + 1,
        latestTimestamp: order.timestamp
      }), {
        total: 0,
        ordersProcessed: 0,
        latestTimestamp: new Date()
      })
      .map(state => ({
        checkpoint: Math.floor(state.total / target) * target,
        ordersNeeded: state.ordersProcessed,
        timestamp: state.latestTimestamp
      }))
  }
}

// Usage
const analyzer = new OrderAnalyzer([
  {
    orderId: 'ORD1',
    amount: 100,
    items: 2,
    timestamp: new Date('2024-01-01')
  },
  {
    orderId: 'ORD2',
    amount: 200,
    items: 3,
    timestamp: new Date('2024-01-02')
  }
])

const metrics = analyzer.getRunningMetrics()

Type Safety

typescript
interface Metrics {
  count: number
  total: number
}

const data = collect([10, 20, 30])

// Type-safe accumulation
const runningMetrics: CollectionOperations<Metrics> = data.scan(
  (acc, value) => ({
    count: acc.count + 1,
    total: acc.total + value
  }),
  { count: 0, total: 0 }
)

// TypeScript enforces accumulator type
const result: Metrics = runningMetrics.last()!

Return Value

  • Returns a Collection of all intermediate accumulation results
  • Each item represents state after processing an element
  • Collection length equals input length
  • Maintains type safety through generics
  • Preserves collection chain methods
  • First result includes initial value

Common Use Cases

1. Financial Analysis

  • Running balances
  • Cumulative totals
  • Transaction history
  • Revenue tracking
  • Budget monitoring

2. Progress Tracking

  • Completion percentages
  • Milestone tracking
  • Task progress
  • Goal achievement
  • Step-by-step status

3. Performance Metrics

  • Running averages
  • Cumulative stats
  • Performance history
  • Resource usage
  • Load tracking

4. Time Series

  • Running calculations
  • Trend analysis
  • Sequential processing
  • Historical states
  • Data accumulation

5. Inventory Management

  • Stock levels
  • Order fulfillment
  • Supply tracking
  • Usage patterns
  • Reorder points

Released under the MIT License.