# List Operations at the Edge, Zero Dependencies

> Functional utilities for arrays and collections with automatic type inference and lazy evaluation. Filter, map, reduce, sort, and transform data at the edge.

Canonical: https://lists.do/

## In code

```ts
import { Lists } from 'lists.do'

// Transform collections at the edge
on.Data.requested($ => {
  const users = $.Database.query.Users({ limit: 10000 })

  const topCustomers = Lists(users)
    .filter(u => u.lastLogin > Date.now() - 30 * 86400000)
    .map(u => ({ ...u, revenue: calculate(u) }))
    .sortBy('revenue', 'desc')
    .take(100)
    .groupBy('country')
    .value()

  return $.Response.cached({ data: topCustomers, ttl: '1h' })
})
```

## Frequently asked questions

### What list operations are supported?

Filter, map, reduce, forEach, find, findIndex, some, every, sort, sortBy, reverse, unique, flatten, flatMap, groupBy, partition, chunk, take, skip, concat, zip, unzip, difference, intersection, union, compact, and 50+ more functional utilities. All operations support lazy evaluation and method chaining. Full TypeScript type inference across the entire pipeline—no type assertions needed.

### How does lists.do compare to Lodash performance-wise?

Lists.do runs at the edge with <1ms P99 latency vs 50-200ms cold starts for serverless functions with Lodash. Zero bundle size (no npm packages to download) vs 70KB minified Lodash. Automatic result caching at 300+ locations globally. Operations are optimized for V8 engine with zero-copy transformations where possible. For typical workloads, 10-100x faster than serverless + Lodash.

### Can I process large datasets efficiently?

Yes. Lazy evaluation means operations aren't executed until .value() is called—only process what you need. Streaming support for datasets >10MB. Automatic pagination for database queries. Smart caching prevents recomputing identical transformations. Process millions of records with memory-efficient iterators. Parallel execution across multiple edge workers for very large datasets (>100MB).

### How does type inference work?

Full TypeScript type inference across method chains. After .filter(user => user.age > 18), TypeScript knows age exists and is a number. After .map(user => user.email), the type becomes string[]. No manual type assertions or generic parameters needed. IDE autocomplete works perfectly throughout the pipeline. Type errors caught at compile time, not runtime.

### Can I use custom comparison and transformation functions?

Yes. All methods accept custom functions: filter(customPredicate), map(customTransform), sortBy(customComparator), groupBy(customKeySelector), reduce(customReducer). Functions can be async—Lists.do automatically handles promises. Reference external data, call APIs, or perform complex logic in your transformations. All functions run at the edge with full access to the .do ecosystem.

## Part of Platform.do

lists.do is one of the primitives of Platform.do, in the Data layer (records, vocabulary and search). Every .do shares one grammar, Business-as-Code, and one SDK.

- What is Business-as-Code? https://platform.do/business-as-code
- Platform.do: https://platform.do/
- Docs: https://docs.platform.do
