Skip to content

Reduce Method ​

The reduce() method reduces the collection to a single value by iterating through the collection and applying an accumulator function to each element. The accumulator function receives the accumulated value, current value, and current index.

Basic Syntax ​

typescript
collect(items).reduce<U>(
  callback: (accumulator: U, current: T, index: number) => U,
  initialValue: U
): U

Examples ​

Basic Usage ​

typescript
import { collect } from 'ts-collect'

// Sum numbers
const numbers = collect([1, 2, 3, 4, 5])
const sum = numbers.reduce((acc, num) => acc + num, 0)
console.log(sum) // 15

// Concatenate strings
const words = collect(['Hello', 'world', '!'])
const sentence = words.reduce((acc, word) => `${acc} ${word}`, '').trim()
console.log(sentence) // "Hello world !"

Working with Objects ​

typescript
interface CartItem {
  id: number
  name: string
  price: number
  quantity: number
}

const cart = collect<CartItem>([
  { id: 1, name: 'Item 1', price: 10, quantity: 2 },
  { id: 2, name: 'Item 2', price: 15, quantity: 1 },
  { id: 3, name: 'Item 3', price: 20, quantity: 3 }
])

// Calculate total price
const total = cart.reduce((acc, item) =>
  acc + (item.price * item.quantity), 0)
console.log(total) // 85

Real-world Examples ​

Analytics Aggregator ​

typescript
interface MetricPoint {
  timestamp: Date
  value: number
  category: string
}

interface Aggregation {
  sum: number
  count: number
  min: number
  max: number
  avg: number
}

class MetricsAggregator {
  aggregate(points: MetricPoint[]): Aggregation {
    return collect(points).reduce<Aggregation>(
      (acc, point) => ({
        sum: acc.sum + point.value,
        count: acc.count + 1,
        min: Math.min(acc.min, point.value),
        max: Math.max(acc.max, point.value),
        avg: (acc.sum + point.value) / (acc.count + 1)
      }),
      { sum: 0, count: 0, min: Infinity, max: -Infinity, avg: 0 }
    )
  }
}

Path Builder ​

typescript
interface PathSegment {
  type: 'directory' | 'file'
  name: string
}

class PathBuilder {
  buildPath(segments: PathSegment[]): string {
    return collect(segments).reduce((path, segment, index) => {
      if (index === 0)
        return segment.name
      return segment.type === 'directory'
        ? `${path}/${segment.name}`
        : `${path}/${segment.name}`
    }, '')
  }

  buildWindowsPath(segments: PathSegment[]): string {
    return collect(segments).reduce((path, segment, index) => {
      if (index === 0)
        return segment.name
      return `${path}\\${segment.name}`
    }, '')
  }
}

Advanced Usage ​

State Machine ​

typescript
interface State {
  name: string
  data: any
}

interface Transition {
  from: string
  to: string
  action: string
  payload?: any
}

class StateMachine {
  processTransitions(
    initialState: State,
    transitions: Transition[]
  ): State {
    return collect(transitions).reduce(
      (currentState, transition) => {
        if (transition.from !== currentState.name) {
          throw new Error('Invalid transition')
        }

        return {
          name: transition.to,
          data: this.processStateData(
            currentState.data,
            transition.action,
            transition.payload
          )
        }
      },
      initialState
    )
  }

  private processStateData(
    currentData: any,
    action: string,
    payload?: any
  ): any {
    // State data processing logic
    return { ...currentData, ...payload }
  }
}

Query Builder ​

typescript
interface QueryPart {
  type: 'select' | 'where' | 'orderBy'
  value: string
}

class QueryBuilder {
  buildQuery(parts: QueryPart[]): string {
    return collect(parts).reduce((query, part, index) => {
      switch (part.type) {
        case 'select':
          return `SELECT ${part.value}`
        case 'where':
          return `${query} WHERE ${part.value}`
        case 'orderBy':
          return `${query} ORDER BY ${part.value}`
        default:
          return query
      }
    }, '')
  }
}

Type Safety ​

typescript
interface TypedItem {
  id: number
  value: number
  metadata?: Record<string, any>
}

interface Summary {
  total: number
  count: number
  items: number[]
}

const items = collect<TypedItem>([
  { id: 1, value: 10 },
  { id: 2, value: 20, metadata: { important: true } },
  { id: 3, value: 30 }
])

// Type-safe reduction
const summary = items.reduce<Summary>(
  (acc, item) => ({
    total: acc.total + item.value,
    count: acc.count + 1,
    items: [...acc.items, item.id]
  }),
  { total: 0, count: 0, items: [] }
)

Return Value ​

  • Returns a single value of type U (specified by initialValue)
  • The value type can be different from the collection item type
  • The returned value is built up through each iteration
  • Initial value is required and used as starting point
  • Type safety is maintained through TypeScript generics
  • Can be used with any accumulator value type

Common Use Cases ​

1. Number Operations ​

  • Summing values
  • Calculating averages
  • Finding min/max values
  • Computing running totals

2. String Operations ​

  • Building concatenated strings
  • Creating HTML/XML
  • Generating formatted text
  • Building URLs

3. Object Aggregation ​

  • Merging objects
  • Building complex objects
  • Grouping data
  • Creating summaries

4. State Management ​

  • Building state objects
  • Tracking changes
  • Computing derived state
  • Managing transitions

5. Data Transformation ​

  • Converting data structures
  • Building hierarchies
  • Reshaping data
  • Creating indexes

6. Statistical Calculations ​

  • Computing averages
  • Calculating variance
  • Finding medians
  • Building histograms

7. Collection Operations ​

  • Grouping items
  • Creating maps
  • Building sets
  • Merging collections

8. Tree Operations ​

  • Building tree structures
  • Traversing hierarchies
  • Computing tree properties
  • Accumulating path data

9. Query Building ​

  • Constructing SQL queries
  • Building API parameters
  • Creating filter chains
  • Composing URLs

10. Report Generation ​

  • Building summaries
  • Creating aggregations
  • Generating statistics
  • Compiling results

Released under the MIT License.