SwissList
A functional, immutable list implementation with a rich set of methods for manipulating collections in TypeScript.
Features
- 🛡️ Type Safety: Fully typed with TypeScript
- 🔄 Immutable: All operations return new instances
- 🧩 Functional: Rich set of functional programming methods
- 🚀 Performance: Optimized for common operations
- 📦 Zero Dependencies: Lightweight and self-contained
Installation
npm install swisslist
Usage
Basic Usage
import { List } from 'swisslist'
// Create a new list
const list = List.of(1, 2, 3, 4, 5)
// Transform elements
const doubled = list.map((x) => x * 2)
// Filter elements
const evenNumbers = list.filter((x) => x % 2 === 0)
// Reduce elements
const sum = list.reduce((acc, curr) => acc + curr, 0)
// Chain operations
const result = list
.filter((x) => x > 2)
.map((x) => x * 3)
.take(2)
React Example: Todo List
Here's how you can use SwissList to manage a todo list state in React:
import { useState } from 'react'
import { List } from 'swisslist'
interface Todo {
id: number
text: string
completed: boolean
}
function TodoList() {
const [todos, setTodos] = useState(List.empty<Todo>())
// Add a new todo
const addTodo = (text: string) => {
setTodos((current) =>
current.append({
id: Date.now(),
text,
completed: false,
}),
)
}
// Toggle todo completion using updateWhere
const toggleTodo = (id: number) => {
setTodos((current) =>
current.updateWhere(
(todo) => todo.id === id,
(todo) => ({ ...todo, completed: !todo.completed }),
),
)
}
// Remove a todo using the index from map
const removeTodo = (index: number) => {
setTodos((current) => current.removeAt(index))
}
// Move a todo up or down in the list
const moveTodo = (index: number, direction: 'up' | 'down') => {
setTodos((current) => {
const newIndex = direction === 'up' ? index - 1 : index + 1
return current.move(index, newIndex)
})
}
// Get active todos
const activeTodos = todos.filter((todo) => !todo.completed)
return (
<div>
<input
type="text"
onKeyDown={(e) => {
if (e.key === 'Enter') {
addTodo(e.currentTarget.value)
e.currentTarget.value = ''
}
}}
/>
<ul>
{todos.map((todo, index) => (
<li key={todo.id}>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
<span
style={{
textDecoration: todo.completed ? 'line-through' : 'none',
}}
>
{todo.text}
</span>
<button onClick={() => removeTodo(index)}>Delete</button>
<button
onClick={() => moveTodo(index, 'up')}
disabled={todos.isFirst(index)}
>
↑
</button>
<button
onClick={() => moveTodo(index, 'down')}
disabled={todos.isLast(index)}
>
↓
</button>
</li>
))}
</ul>
<p>Active todos: {activeTodos.size}</p>
</div>
)
}
Mathematical Operations
SwissList provides a rich set of mathematical operations that work with any type of data through selector functions:
import { List } from 'swisslist'
// Example: Working with a list of products
interface Product {
name: string
price: number
quantity: number
}
const products = List.of<Product>(
{ name: 'Apple', price: 1.5, quantity: 10 },
{ name: 'Banana', price: 0.5, quantity: 20 },
{ name: 'Orange', price: 1, quantity: 15 },
{ name: 'Mango', price: 2, quantity: 8 },
)
// Calculate total value of inventory
const totalValue = products.sumBy((p) => p.price * p.quantity)
console.log(`Total inventory value: $${totalValue}`) // $45.5
// Find average price
const avgPrice = products.averageBy((p) => p.price)
console.log(`Average price: $${avgPrice}`) // $1.25
// Find median quantity
const medianQuantity = products.medianBy((p) => p.quantity)
console.log(`Median quantity: ${medianQuantity}`) // 12.5
// Calculate price range
const priceRange = products.rangeBy((p) => p.price)
console.log(`Price range: $${priceRange}`) // $1.5
// Find most common quantity
const modeQuantity = products.modeBy((p) => p.quantity)
console.log(`Most common quantity: ${modeQuantity}`) // 10
// Calculate geometric mean of quantities
const geoMeanQuantity = products.geometricMeanBy((p) => p.quantity)
console.log(`Geometric mean of quantities: ${geoMeanQuantity}`) // 12.649110640673518
// Calculate standard deviation of prices
const priceStdDev = products.standardDeviationBy((p) => p.price)
console.log(`Price standard deviation: $${priceStdDev}`) // $0.6454972243679028
// Example: Working with student grades
interface Student {
name: string
grades: number[]
}
const students = List.of<Student>(
{ name: 'Alice', grades: [85, 90, 88] },
{ name: 'Bob', grades: [92, 88, 95] },
{ name: 'Charlie', grades: [78, 85, 80] },
)
// Calculate average grade for each student
const studentAverages = students.map((student) => ({
name: student.name,
average: List.from(student.grades).averageBy((g) => g),
}))
console.log('Student averages:', studentAverages)
// [
// { name: 'Alice', average: 87.66666666666667 },
// { name: 'Bob', average: 91.66666666666667 },
// { name: 'Charlie', average: 81 }
// ]
// Find the student with the highest average
const bestStudent = studentAverages.reduce(
(best, current) => (current.average > best.average ? current : best),
studentAverages[0],
)
console.log(`Best performing student: ${bestStudent.name}`) // Bob
// Example: Chaining mathematical operations
const salesData = List.of(
{ product: 'A', sales: [100, 120, 90, 110] },
{ product: 'B', sales: [80, 85, 95, 100] },
{ product: 'C', sales: [150, 140, 160, 155] },
)
// Calculate statistics for products with average sales above 100
const highPerformingProducts = salesData
.map((data) => ({
product: data.product,
average: List.from(data.sales).averageBy((s) => s),
stdDev: List.from(data.sales).standardDeviationBy((s) => s),
}))
.filter((data) => data.average > 100)
.sort((a, b) => b.average - a.average)
console.log('High performing products:', highPerformingProducts)
// [
// { product: 'C', average: 151.25, stdDev: 8.539125638299666 },
// { product: 'A', average: 105, stdDev: 12.909944487358056 }
// ]
These mathematical operations are particularly useful for:
- Data analysis and statistics
- Financial calculations
- Grade management systems
- Inventory management
- Performance metrics
- Scientific computations