List Operations

Master list and collection operations in Topaz. Learn advanced manipulation techniques for arrays, maps, sets, and all collection types.

Topaz provides powerful list and collection operations to efficiently handle data structures. All operations support immutability and functional programming. 📊

📋 Array Operations

Array Creation and Initialization

// Various array creation methods
let emptyArray: Array<int> = []
let numberArray = [1, 2, 3, 4, 5]
let stringArray = ["apple", "banana", "cherry"]

// Create arrays with repetition
let repeatedArray = Array.fill(10, 0)              // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
let rangeArray = Array.range(1, 6)                 // [1, 2, 3, 4, 5]
let generatedArray = Array.generate(5, i => i * 2) // [0, 2, 4, 6, 8]

// Type inference and generics
let mixedArray: Array<any> = [1, "hello", true]
let genericArray: Array<T> = Array.new()

print("Number array: {numberArray}")
print("Range array: {rangeArray}")
print("Generated array: {generatedArray}")

Array Transformation Operations

let originalArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// map - transform each element
let squaredArray = originalArray.map(x => x * x)
let stringArray = originalArray.map(x => "Number: {x}")
let objectArray = originalArray.map(x => { value: x, square: x * x })

// flatMap - combine flattening and mapping
let nestedArray = [[1, 2], [3, 4], [5, 6]]
let flattened = nestedArray.flatMap(arr => arr)     // [1, 2, 3, 4, 5, 6]

// Conditional mapping
let conditionalTransform = originalArray.map(x => {
    if x % 2 == 0 {
        return x * 2
    } else {
        return x
    }
})

print("Squared array: {squaredArray}")
print("Flattened: {flattened}")
print("Conditional transform: {conditionalTransform}")

Array Filtering Operations

let testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

// Basic filtering
let evenFilter = testArray.filter(x => x % 2 == 0)     // [2, 4, 6, 8, 10, 12, 14]
let largeFilter = testArray.filter(x => x > 10)        // [11, 12, 13, 14, 15]

// Complex condition filtering
let complexFilter = testArray.filter(x => x % 2 == 0 && x > 5)  // [6, 8, 10, 12, 14]

// Index-based filtering
let indexFilter = testArray.filterWithIndex((value, index) => index % 3 == 0)

// Type filtering
let mixedData: Array<any> = [1, "hello", 3.14, true, "world", 42]
let numbersOnly = mixedData.filter(x => match x {
    case _: int => true
    case _: float => true
    case _ => false
})     // [1, 3.14, 42]
let stringsOnly = mixedData.filter(x => match x {
    case _: string => true
    case _ => false
})     // ["hello", "world"]

print("Even filter: {evenFilter}")
print("Complex filter: {complexFilter}")
print("Numbers only: {numbersOnly}")

Array Accumulation Operations

let numbers = [1, 2, 3, 4, 5]

// reduce - basic accumulation
let sum = numbers.reduce((acc, curr) => acc + curr, 0)        // 15
let product = numbers.reduce((acc, curr) => acc * curr, 1)    // 120
let maximum = numbers.reduce((acc, curr) => Math.max(acc, curr), numbers[0])

// reduceRight - accumulate from right
let rightAccumulation = numbers.reduceRight((acc, curr) => acc + curr, 0)

// scan - include intermediate results
let cumulativeSum = numbers.scan((acc, curr) => acc + curr, 0)     // [0, 1, 3, 6, 10, 15]

// Complex accumulation operation
let statistics = numbers.reduce((acc, curr) => {
    return {
        sum: acc.sum + curr,
        count: acc.count + 1,
        max: Math.max(acc.max, curr),
        min: Math.min(acc.min, curr)
    }
}, { sum: 0, count: 0, max: -Infinity, min: Infinity })

print("Sum: {sum}")
print("Cumulative sum: {cumulativeSum}")
print("Statistics: {statistics}")

🔍 Array Search and Sorting

Search Operations

let dataArray = [10, 25, 8, 15, 32, 7, 18, 42, 3, 29]

// Basic search
let found = dataArray.find(x => x > 20)              // Some(25)
let foundIndex = dataArray.findIndex(x => x > 20)    // Some(1)
let foundLast = dataArray.findLast(x => x > 20)      // Some(42)

// Multiple search
let allLarge = dataArray.filter(x => x > 20)         // [25, 32, 42, 29]
let firstThree = dataArray.take(3)                   // [10, 25, 8]
let lastThree = dataArray.takeLast(3)                // [42, 3, 29]

// Conditional search
let conditionalSearch = dataArray.takeWhile(x => x != 32)     // [10, 25, 8, 15]
let conditionalSkip = dataArray.skipWhile(x => x < 20)       // [25, 8, 15, 32, 7, 18, 42, 3, 29]

// Binary search (on sorted array)
let sortedArray = [1, 3, 5, 7, 9, 11, 13, 15]
let binarySearchResult = sortedArray.binarySearch(9)          // Some(4)

print("Found result: {found}")
print("All large: {allLarge}")
print("Conditional search: {conditionalSearch}")

Sorting Operations

let randomArray = [64, 34, 25, 12, 22, 11, 90, 5]

// Basic sorting
let ascending = randomArray.sort()                      // [5, 11, 12, 22, 25, 34, 64, 90]
let descending = randomArray.sortDescending()           // [90, 64, 34, 25, 22, 12, 11, 5]

// Custom sorting
let customSort = randomArray.sortBy((a, b) => {
    if a % 2 == 0 && b % 2 != 0 { return -1 }    // Even numbers first
    if a % 2 != 0 && b % 2 == 0 { return 1 }     // Odd numbers last
    return a - b                                   // Same type in ascending order
})

// Object array sorting
let users = [
    { name: "John", age: 25, score: 85 },
    { name: "Alice", age: 30, score: 92 },
    { name: "Bob", age: 20, score: 78 }
]

let sortedByAge = users.sortBy(user => user.age)
let sortedByScore = users.sortByDescending(user => user.score)
let multipleSort = users.sortBy([
    user => user.score,      // 1st: score ascending
    user => -user.age        // 2nd: age descending
])

print("Custom sort: {customSort}")
print("Sorted by age: {sortedByAge}")
print("Sorted by score: {sortedByScore}")

📊 Set Operations

Set Creation and Basic Operations

// Set creation
let emptySet: Set<int> = Set.new()
let numberSet = Set.from([1, 2, 3, 4, 5])
let deduplicatedSet = Set.from([1, 1, 2, 2, 3, 3])    // {1, 2, 3}

// Basic set operations
let mut mutableSet = Set.from([1, 2, 3])
mutableSet.add(4)                                      // {1, 2, 3, 4}
mutableSet.remove(2)                                   // {1, 3, 4}

let containsCheck = mutableSet.contains(3)             // true
let size = mutableSet.size()                           // 3

// Set conversion
let toArray = mutableSet.toArray()                     // [1, 3, 4]
let toList = mutableSet.toList()                       // List(1, 3, 4)

print("Number set: {numberSet}")
print("Mutable set: {mutableSet}")

Set Mathematical Operations

let setA = Set.from([1, 2, 3, 4, 5])
let setB = Set.from([4, 5, 6, 7, 8])
let setC = Set.from([1, 3, 5, 7, 9])

// Union
let union = setA.union(setB)                     // {1, 2, 3, 4, 5, 6, 7, 8}

// Intersection
let intersection = setA.intersection(setB)       // {4, 5}

// Difference
let difference = setA.difference(setB)           // {1, 2, 3}

// Symmetric Difference
let symmetricDifference = setA.symmetricDifference(setB)   // {1, 2, 3, 6, 7, 8}

// Subset check
let isSubset = Set.from([1, 2]).isSubsetOf(setA)    // true
let isSuperset = setA.isSupersetOf(Set.from([1, 2]))  // true

// Intersection existence check
let intersects = setA.intersects(setB)            // true

print("Union: {union}")
print("Intersection: {intersection}")
print("Difference: {difference}")
print("Symmetric difference: {symmetricDifference}")

🗺️ Map Operations

Map Creation and Basic Operations

// Map creation
let emptyMap: Map<string, int> = Map.new()
let scoreMap = Map.from([
    ["John", 85],
    ["Alice", 92],
    ["Bob", 78]
])

// Basic map operations
let mut mutableMap = Map.new()
mutableMap.set("apple", 1000)
mutableMap.set("banana", 1500)
mutableMap.set("orange", 2000)

let getValue = mutableMap.get("apple")                 // Some(1000)
let hasKey = mutableMap.has("banana")                  // true
let sizeCheck = mutableMap.size()                      // 3

// Get with default value
let defaultValue = mutableMap.getOrDefault("grape", 0)         // 0

// Map iteration
mutableMap.forEach((value, key) => {
    print("{key}: {value}")
})

print("Score map: {scoreMap}")
print("Mutable map: {mutableMap}")

Map Transformation and Filtering

let productMap = Map.from([
    ["laptop", 1500000],
    ["mouse", 50000],
    ["keyboard", 120000],
    ["monitor", 300000],
    ["speaker", 80000]
])

// Map transformation
let discountPrices = productMap.map((price, product) => price * 0.9)
let productDescriptions = productMap.map((price, product) => "{product}: {price}")

// Map filtering
let expensiveProducts = productMap.filter((price, product) => price > 100000)
let specificProducts = productMap.filterKeys(product => product.contains("top"))

// Extract keys and values
let allKeys = productMap.keys()                        // ["laptop", "mouse", ...]
let allValues = productMap.values()                    // [1500000, 50000, ...]
let entries = productMap.entries()                     // [["laptop", 1500000], ...]

// Merge maps
let additionalProducts = Map.from([["tablet", 800000], ["charger", 30000]])
let mergedMap = productMap.merge(additionalProducts)

print("Discount prices: {discountPrices}")
print("Expensive products: {expensiveProducts}")
print("All keys: {allKeys}")

📝 Advanced List Operations

Functional List Operations

let numberList = List.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

// Chaining operations
let complexOperationResult = numberList
    .filter(x => x % 2 == 0)        // Even numbers only
    .map(x => x * x)                // Square
    .take(3)                        // First 3
    .sum()                          // Sum

// Partition operations
let (evens, odds) = numberList.partition(x => x % 2 == 0)
let groupedByRemainder = numberList.groupBy(x => x % 3)    // Group by remainder

// Window operations (sliding window)
let window3 = numberList.windowed(3)              // [[1,2,3], [2,3,4], [3,4,5], ...]
let chunk2 = numberList.chunked(2)                // [[1,2], [3,4], [5,6], [7,8], [9,10]]

// zip operations
let charList = List.from(["a", "b", "c", "d", "e"])
let zippedResult = numberList.zip(charList)       // [(1,"a"), (2,"b"), (3,"c"), (4,"d"), (5,"e")]

print("Complex operation result: {complexOperationResult}")
print("Evens: {evens}, Odds: {odds}")
print("Window 3: {window3}")
print("Zipped result: {zippedResult}")

List Aggregation Operations

let scoreList = List.from([85, 92, 78, 96, 84, 88, 79, 91])

// Basic aggregation
let total = scoreList.sum()                       // 693
let average = scoreList.average()                 // 86.625
let maximum = scoreList.max()                     // Some(96)
let minimum = scoreList.min()                     // Some(78)
let count = scoreList.count()                     // 8

// Conditional aggregation
let highScoreCount = scoreList.count(x => x >= 90)  // 3
let highScoreSum = scoreList.sumBy(x => if x >= 90 { x } else { 0 })

// Statistical calculations
let variance = scoreList.variance()
let standardDeviation = scoreList.standardDeviation()
let median = scoreList.median()

// Custom aggregation
let customAggregate = scoreList.aggregate(
    initial: { sum: 0, count: 0, highest: 0 },
    func: (acc, current) => {
        return {
            sum: acc.sum + current,
            count: acc.count + 1,
            highest: Math.max(acc.highest, current)
        }
    }
)

print("Average: {average}")
print("Standard deviation: {standardDeviation}")
print("Custom aggregate: {customAggregate}")

🔄 Collection Conversion Operations

Inter-Collection Conversion

// Array ↔ List ↔ Set conversion
let originalArray = [1, 2, 2, 3, 3, 4, 5]
let listConversion = List.from(originalArray)
let setConversion = Set.from(originalArray)          // Duplicates removed
let backToArray = setConversion.toArray()

// Convert to map
let keyValuePairs = [["a", 1], ["b", 2], ["c", 3]]
let mapConversion = Map.from(keyValuePairs)

// Grouping conversion
let studentScores = [
    { name: "John", subject: "Math", score: 85 },
    { name: "John", subject: "English", score: 90 },
    { name: "Alice", subject: "Math", score: 95 },
    { name: "Alice", subject: "English", score: 88 }
]

let groupedByStudent = studentScores.groupBy(x => x.name)
let groupedBySubject = studentScores.groupBy(x => x.subject)

// Map indexing
let nameIndex = studentScores.associateBy(x => x.name)
let keyValueMapping = studentScores.associate(x => [x.name, x.score])

print("Set conversion: {setConversion}")
print("Grouped by student: {groupedByStudent}")
print("Name index: {nameIndex}")

⚡ Performance Optimization Operations

Lazy Evaluation

// Lazy evaluation sequence
let largeArray = Array.range(1, 1000000)

// Eager evaluation (high memory usage)
let eagerResult = largeArray
    .filter(x => x % 2 == 0)
    .map(x => x * x)
    .take(10)

// Lazy evaluation (memory efficient)
let lazySequence = largeArray
    .asSequence()
    .filter(x => x % 2 == 0)
    .map(x => x * x)
    .take(10)
    .toList()

// Infinite sequence
let fibonacciSequence = Sequence.generate(
    initial: [0, 1],
    generator: ([a, b]) => [b, a + b]
).map(([a, b]) => a)

let firstTenFibonacci = fibonacciSequence.take(10).toList()

print("Lazy sequence result: {lazySequence}")
print("First ten Fibonacci: {firstTenFibonacci}")

Parallel Processing

// Large data suitable for parallel processing
let largeData = Array.range(1, 100000)

// Sequential processing
let sequentialResult = largeData
    .filter(x => isPrime(x))
    .sum()

// Parallel processing
let parallelResult = largeData
    .parallel()
    .filter(x => isPrime(x))
    .sum()

// Prime checking function
function isPrime(n: int) -> bool {
    if n < 2 { return false }
    for i in 2..Math.sqrt(n) {
        if n % i == 0 { return false }
    }
    return true
}

// Parallel map-reduce
let parallelMapReduce = largeData
    .parallel()
    .map(x => x * x)
    .reduce((a, b) => a + b, 0)

print("Parallel result: {parallelResult}")

🛠️ Custom Collections

Custom Collection Implementation

// Stack implementation
struct Stack<T> {
    items: Array<T>
}

impl<T> Stack<T> {
    function new() -> Stack<T> {
        return Stack { items: [] }
    }
    
    function push(item: T) {
        self.items.push(item)
    }
    
    function pop() -> Option<T> {
        return self.items.pop()
    }
    
    function peek() -> Option<T> {
        return self.items.last()
    }
    
    function isEmpty() -> bool {
        return self.items.isEmpty()
    }
    
    function size() -> int {
        return self.items.length()
    }
    
    // Iterator implementation
    function iterator() -> Iterator<T> {
        return self.items.reverse().iterator()
    }
}

// Usage example
let mut stack = Stack.new()
stack.push(1)
stack.push(2)
stack.push(3)

let top = stack.peek()                      // Some(3)
let popped = stack.pop()                    // Some(3)

for item in stack {
    print("Stack item: {item}")
}

print("Top: {top}")
print("Popped: {popped}")

Specialized Collection Operations

// Priority queue
let priorityQueue = PriorityQueue.new((a, b) => a - b)  // Min heap
priorityQueue.enqueue(5)
priorityQueue.enqueue(2)
priorityQueue.enqueue(8)
priorityQueue.enqueue(1)

while !priorityQueue.isEmpty() {
    let minimum = priorityQueue.dequeue()
    print("Priority: {minimum}")                // 1, 2, 5, 8 order
}

// TreeMap (sorted map)
let treeMap = TreeMap.new()
treeMap.put("c", 3)
treeMap.put("a", 1)
treeMap.put("b", 2)

// Output in sorted order
for (key, value) in treeMap {
    print("{key}: {value}")                      // a:1, b:2, c:3 order
}

// MultiMap (multiple values per key)
let multiMap = MultiMap.new()
multiMap.put("fruits", "apple")
multiMap.put("fruits", "banana")
multiMap.put("vegetables", "carrot")

let fruits = multiMap.get("fruits")               // ["apple", "banana"]

print("Fruits: {fruits}")

Topaz list operations make data processing efficient and expressive. Use immutability and functional programming to write safe and readable code! 🎯