Exemples de Structures de Données macOS Swift

Exemples de structures de données macOS Swift incluant les opérations de tableaux, tables de hachage et listes chaînées

Key Facts

Category
Swift
Items
3
Format Families
sample

Sample Overview

Exemples de structures de données macOS Swift incluant les opérations de tableaux, tables de hachage et listes chaînées This sample set belongs to Swift and can be used to test related workflows inside Elysia Tools.

💻 Opérations sur Tableaux swift

🟢 simple ⭐⭐

Manipulation complète des tableaux incluant les opérations CRUD, le tri, la recherche et les transformations

⏱️ 30 min 🏷️ swift, macos, data structures, arrays
Prerequisites: Basic Swift knowledge
// macOS Swift Array Operations Examples
// Using Swift standard library

import Foundation

// 1. Basic Array Creation and Initialization
class ArrayBasics {

    static func demonstrateCreation() {
        print("\n--- Array Creation ---")

        // Empty array
        let emptyArray: [Int] = []
        let emptyArray2 = [Int]()
        print("Empty arrays: \(emptyArray), \(emptyArray2)")

        // Array with values
        let numbers = [1, 2, 3, 4, 5]
        print("Numbers: \(numbers)")

        // Array with repeated values
        let repeated = Array(repeating: 0, count: 5)
        print("Repeated zeros: \(repeated)")

        // Array from sequence
        let range = Array(1...10)
        print("Range array: \(range)")

        // Array of strings
        let fruits = ["Apple", "Banana", "Cherry"]
        print("Fruits: \(fruits)")

        // Array with default values and capacity
        var arrayWithCapacity = [Int]()
        arrayWithCapacity.reserveCapacity(10)
        print("Array with capacity: \(arrayWithCapacity.capacity)")
    }
}

// 2. Array CRUD Operations
class ArrayCRUD {

    static func demonstrateCRUD() {
        print("\n--- Array CRUD Operations ---")

        var numbers = [10, 20, 30, 40, 50]

        // READ - Access elements
        print("First element: \(numbers.first ?? 0)")
        print("Last element: \(numbers.last ?? 0)")
        print("Element at index 2: \(numbers[2])")
        print("First 3 elements: \(numbers.prefix(3))")
        print("Last 2 elements: \(numbers.suffix(2))")

        // UPDATE - Modify elements
        numbers[1] = 25
        print("After update: \(numbers)")

        numbers.replaceSubrange(0...2, with: [5, 15, 25])
        print("After replace range: \(numbers)")

        // CREATE - Add elements
        numbers.append(60)
        print("After append: \(numbers)")

        numbers += [70, 80]
        print("After add array: \(numbers)")

        numbers.insert(35, at: 3)
        print("After insert: \(numbers)")

        // DELETE - Remove elements
        let removed = numbers.remove(at: 2)
        print("Removed element: \(removed), Array: \(numbers)")

        numbers.removeFirst()
        numbers.removeLast()
        print("After remove first and last: \(numbers)")

        numbers.removeAll { $0 > 50 }
        print("After remove > 50: \(numbers)")

        numbers.removeAll()
        print("After remove all: \(numbers)")
    }
}

// 3. Array Iteration
class ArrayIteration {

    static func demonstrateIteration() {
        print("\n--- Array Iteration ---")

        let fruits = ["Apple", "Banana", "Cherry", "Date", "Elderberry"]

        // For-in loop
        print("For-in loop:")
        for fruit in fruits {
            print("  \(fruit)")
        }

        // With index
        print("\nWith enumerated:")
        for (index, fruit) in fruits.enumerated() {
            print("  \(index): \(fruit)")
        }

        // While loop
        print("\nWhile loop:")
        var i = 0
        while i < fruits.count {
            print("  \(fruits[i])")
            i += 1
        }

        // ForEach
        print("\nForEach:")
        fruits.forEach { fruit in
            print("  \(fruit)")
        }

        // With indices
        print("\nWith indices:")
        for index in fruits.indices {
            print("  fruits[\(index)] = \(fruits[index])")
        }
    }
}

// 4. Array Sorting
class ArraySorting {

    static func demonstrateSorting() {
        print("\n--- Array Sorting ---")

        var numbers = [5, 2, 8, 1, 9, 3, 7, 4, 6]
        print("Original: \(numbers)")

        // Ascending sort
        let ascending = numbers.sorted()
        print("Ascending: \(ascending)")

        // Descending sort
        let descending = numbers.sorted(by: >)
        print("Descending: \(descending)")

        // In-place sort
        numbers.sort()
        print("In-place sorted: \(numbers)")

        // Sort strings
        var names = ["John", "Alice", "Bob", "Zoe", "Charlie"]
        names.sort()
        print("Sorted names: \(names)")

        // Case-insensitive sort
        let mixed = ["apple", "Banana", "cherry", "Date"]
        let caseInsensitive = mixed.sorted { $0.lowercased() < $1.lowercased() }
        print("Case-insensitive: \(caseInsensitive)")

        // Custom sort - by length
        let words = ["a", "aaa", "aa", "aaaa"]
        let byLength = words.sorted { $0.count < $1.count }
        print("By length: \(byLength)")

        // Sort complex objects
        struct Person {
            let name: String
            let age: Int
        }

        let people = [
            Person(name: "Alice", age: 30),
            Person(name: "Bob", age: 25),
            Person(name: "Charlie", age: 35)
        ]

        let byAge = people.sorted { $0.age < $1.age }
        print("People sorted by age:")
        for person in byAge {
            print("  \(person.name): \(person.age)")
        }
    }
}

// 5. Array Searching
class ArraySearching {

    static func demonstrateSearching() {
        print("\n--- Array Searching ---")

        let numbers = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

        // Contains
        print("Contains 50: \(numbers.contains(50))")
        print("Contains 55: \(numbers.contains(55))")

        // First index of
        if let index = numbers.firstIndex(of: 40) {
            print("First index of 40: \(index)")
        }

        // Last index of
        let duplicates = [1, 2, 3, 2, 4, 2, 5]
        if let lastIndex = duplicates.lastIndex(of: 2) {
            print("Last index of 2: \(lastIndex)")
        }

        // Find with predicate
        let found = numbers.first { $0 > 50 }
        print("First > 50: \(found ?? 0)")

        // Find all matching
        let allGreaterThan50 = numbers.filter { $0 > 50 }
        print("All > 50: \(allGreaterThan50)")

        // Binary search (requires sorted array)
        let sorted = numbers.sorted()
        let searchIndex = sorted.firstIndex(of: 70)
        print("Binary search result: \(searchIndex ?? -1)")

        // Min and Max
        print("Min: \(numbers.min() ?? 0)")
        print("Max: \(numbers.max() ?? 0)")

        // First and last matching condition
        let numbersWithCondition = [5, 10, 15, 20, 25, 30]
        let firstGreaterThan20 = numbersWithCondition.first { $0 > 20 }
        let lastGreaterThan20 = numbersWithCondition.last { $0 > 20 }
        print("First > 20: \(firstGreaterThan20 ?? 0)")
        print("Last > 20: \(lastGreaterThan20 ?? 0)")
    }
}

// 6. Array Filtering and Transformation
class ArrayFiltering {

    static func demonstrateFiltering() {
        print("\n--- Array Filtering and Transformation ---")

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

        // Filter - even numbers
        let evens = numbers.filter { $0 % 2 == 0 }
        print("Even numbers: \(evens)")

        // Filter - odd numbers
        let odds = numbers.filter { $0 % 2 != 0 }
        print("Odd numbers: \(odds)")

        // Map - transform
        let squared = numbers.map { $0 * $0 }
        print("Squared: \(squared)")

        // Map - to strings
        let strings = numbers.map { "Number \($0)" }
        print("As strings: \(strings)")

        // Compact map - remove nils
        let optionalStrings = ["1", "2", "abc", "4", "5"]
        let validNumbers = optionalStrings.compactMap { Int($0) }
        print("Valid numbers: \(validNumbers)")

        // Flat map - flatten arrays
        let arrayOfArrays = [[1, 2], [3, 4], [5, 6]]
        let flattened = arrayOfArrays.flatMap { $0 }
        print("Flattened: \(flattened)")

        // Reduce - sum
        let sum = numbers.reduce(0, +)
        print("Sum: \(sum)")

        // Reduce - product
        let product = numbers.reduce(1, *)
        print("Product: \(product)")

        // Reduce - custom
        let sentence = ["Hello", "world", "from", "Swift"]
        let joined = sentence.reduce("") { $0 + " " + $1 }
        print("Joined: \(joined)")

        // Chaining operations
        let result = numbers
            .filter { $0 % 2 == 0 }
            .map { $0 * $0 }
            .reduce(0, +)
        print("Sum of squares of evens: \(result)")
    }
}

// 7. Array Operations and Algorithms
class ArrayAlgorithms {

    static func demonstrateAlgorithms() {
        print("\n--- Array Algorithms ---")

        // Reverse
        let numbers = [1, 2, 3, 4, 5]
        print("Original: \(numbers)")
        print("Reversed: \(numbers.reversed())")

        // Shuffle
        var shuffled = numbers
        shuffled.shuffle()
        print("Shuffled: \(shuffled)")

        // Rotate
        var toRotate = [1, 2, 3, 4, 5]
        let first = toRotate.removeFirst()
        toRotate.append(first)
        print("Rotated left: \(toRotate)")

        // Unique elements
        let withDuplicates = [1, 2, 2, 3, 4, 4, 5, 5, 5]
        let unique = Array(Set(withDuplicates))
        print("Unique: \(unique)")

        // Intersection
        let array1 = [1, 2, 3, 4, 5]
        let array2 = [4, 5, 6, 7, 8]
        let intersection = array1.filter { array2.contains($0) }
        print("Intersection: \(intersection)")

        // Union
        let union = Array(Set(array1 + array2))
        print("Union: \(union.sorted())")

        // Difference
        let difference = array1.filter { !array2.contains($0) }
        print("Difference (array1 - array2): \(difference)")

        // Partition
        var toPartition = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        let pivot = toPartition.partition(by: { $0 > 5 })
        print("Partitioned: \(toPartition)")
        print("Pivot index: \(pivot)")

        // Chunk/Split into subarrays
        func chunk<T>(_ array: [T], size: Int) -> [[T]] {
            stride(from: 0, to: array.count, by: size).map {
                Array(array[$0..<min($0 + size, array.count)])
            }
        }

        let largeArray = Array(1...15)
        let chunks = chunk(largeArray, size: 4)
        print("Chunks: \(chunks)")
    }
}

// 8. Multi-dimensional Arrays
class MultiDimensionalArrays {

    static func demonstrateMultiDimensional() {
        print("\n--- Multi-dimensional Arrays ---")

        // 2D Array
        let matrix = [
            [1, 2, 3],
            [4, 5, 6],
            [7, 8, 9]
        ]

        print("Matrix:")
        for row in matrix {
            print("  \(row)")
        }

        // Access element
        print("Element at [1][2]: \(matrix[1][2])")

        // Iterate 2D
        print("\nIterate 2D:")
        for (rowIndex, row) in matrix.enumerated() {
            for (colIndex, element) in row.enumerated() {
                print("  [\(rowIndex)][\(colIndex)] = \(element)")
            }
        }

        // Flatten
        let flat = matrix.flatMap { $0 }
        print("Flattened: \(flat)")

        // Transpose
        func transpose<T>(_ matrix: [[T]]) -> [[T]] {
            guard matrix.count > 0 else { return [] }
            let rowCount = matrix.count
            let colCount = matrix[0].count

            var result = [[T]]()
            for col in 0..<colCount {
                var newRow = [T]()
                for row in 0..<rowCount {
                    newRow.append(matrix[row][col])
                }
                result.append(newRow)
            }
            return result
        }

        let transposed = transpose(matrix)
        print("Transposed:")
        for row in transposed {
            print("  \(row)")
        }
    }
}

// 9. Array Performance and Optimization
class ArrayPerformance {

    static func demonstrateOptimization() {
        print("\n--- Array Performance Tips ---")

        // Reserve capacity
        var array = [Int]()
        array.reserveCapacity(1000)
        print("Reserved capacity: \(array.capacity)")

        // Contiguous storage
        let contiguous = [1, 2, 3, 4, 5]
        withUnsafeBufferPointer(to: contiguous) { buffer in
            print("Contiguous storage: \(buffer.baseAddress != nil)")
        }

        // Efficient append
        var efficient = [Int]()
        efficient.reserveCapacity(10)
        for i in 1...10 {
            efficient.append(i)
        }

        // Pre-allocate vs append
        var preAllocated = [Int](repeating: 0, count: 10)
        for i in 0..<10 {
            preAllocated[i] = i + 1
        }

        // Lazy operations
        let largeNumbers = Array(1...1_000_000)
        let lazyResult = largeNumbers.lazy.filter { $0 % 2 == 0 }.prefix(5)
        print("Lazy result (first 5 evens): \(Array(lazyResult))")
    }
}

// 10. Array Utility Functions
class ArrayUtilities {

    static func demonstrateUtilities() {
        print("\n--- Array Utilities ---")

        // Count elements
        let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        print("Count: \(numbers.count)")

        // Count with condition
        let evensCount = numbers.filter { $0 % 2 == 0 }.count
        print("Even count: \(evensCount)")

        // Check if empty
        print("Is empty: \(numbers.isEmpty)")

        // Random element
        if let random = numbers.randomElement() {
            print("Random element: \(random)")
        }

        // Shuffle
        let shuffled = numbers.shuffled()
        print("Shuffled (first 5): \(Array(shuffled.prefix(5)))")

        // Split
        let sentence = "Hello world from Swift".components(separatedBy: " ")
        print("Split sentence: \(sentence)")

        // Join
        let joined = sentence.joined(separator: "-")
        print("Joined: \(joined)")

        // Zip
        let names = ["Alice", "Bob", "Charlie"]
        let ages = [30, 25, 35]
        let pairs = Array(zip(names, ages))
        print("Zipped: \(pairs)")

        // Indices
        print("Indices: \(numbers.indices)")

        // Slice
        let slice = numbers[2..<6]
        print("Slice [2..<6]: \(Array(slice))")
    }
}

// Main demonstration
func demonstrateArrayOperations() {
    print("=== macOS Swift Array Operations Examples ===")

    ArrayBasics.demonstrateCreation()
    ArrayCRUD.demonstrateCRUD()
    ArrayIteration.demonstrateIteration()
    ArraySorting.demonstrateSorting()
    ArraySearching.demonstrateSearching()
    ArrayFiltering.demonstrateFiltering()
    ArrayAlgorithms.demonstrateAlgorithms()
    MultiDimensionalArrays.demonstrateMultiDimensional()
    ArrayPerformance.demonstrateOptimization()
    ArrayUtilities.demonstrateUtilities()

    print("\n=== All Array Operations Completed ===")
}

// Run demonstration
demonstrateArrayOperations()

💻 Table de Hachage swift

🟡 intermediate ⭐⭐⭐

Implémenter et utiliser des dictionnaires (tables de hachage) pour un stockage et une recherche efficace clé-valeur

⏱️ 35 min 🏷️ swift, macos, data structures, dictionaries
Prerequisites: Intermediate Swift, Hashable protocol
// macOS Swift Hash Table Examples
// Using Swift Dictionary

import Foundation

// 1. Basic Dictionary Operations
class DictionaryBasics {

    static func demonstrateBasics() {
        print("\n--- Dictionary Basics ---")

        // Create empty dictionary
        var emptyDict: [String: Int] = [:]
        var emptyDict2 = [String: Int]()
        print("Empty dictionaries: \(emptyDict), \(emptyDict2)")

        // Create with values
        var scores = ["Alice": 95, "Bob": 87, "Charlie": 92]
        print("Scores: \(scores)")

        // Access value
        if let aliceScore = scores["Alice"] {
            print("Alice's score: \(aliceScore)")
        }

        // Default value
        let bobScore = scores["Bob", default: 0]
        print("Bob's score with default: \(bobScore)")

        // Add or update
        scores["David"] = 88
        print("After adding David: \(scores)")

        scores["Alice"] = 98
        print("After updating Alice: \(scores)")

        // Update with return value
        let oldScore = scores.updateValue(100, forKey: "Charlie")
        print("Charlie's old score: \(oldScore ?? 0)")

        // Remove value
        scores["Bob"] = nil
        let removedScore = scores.removeValue(forKey: "David")
        print("Removed score: \(removedScore ?? 0)")
        print("After removals: \(scores)")
    }
}

// 2. Dictionary Iteration
class DictionaryIteration {

    static func demonstrateIteration() {
        print("\n--- Dictionary Iteration ---")

        let products = [
            "Apple": 1.99,
            "Banana": 0.99,
            "Cherry": 2.99,
            "Date": 3.99
        ]

        // Iterate key-value pairs
        print("Key-value pairs:")
        for (product, price) in products {
            print("  \(product): $\(price)")
        }

        // Iterate keys
        print("\nKeys:")
        for product in products.keys {
            print("  \(product)")
        }

        // Iterate values
        print("\nValues:")
        for price in products.values {
            print("  \(price)")
        }

        // ForEach
        print("\nForEach:")
        products.forEach { product, price in
            print("  \(product): $\(price)")
        }

        // Sorted iteration
        print("\nSorted by key:")
        for product in products.keys.sorted() {
            print("  \(product): $\(products[product] ?? 0)")
        }
    }
}

// 3. Dictionary Operations
class DictionaryOperations {

    static func demonstrateOperations() {
        print("\n--- Dictionary Operations ---")

        var dict1 = ["a": 1, "b": 2, "c": 3]
        var dict2 = ["c": 30, "d": 4, "e": 5]

        print("Dict1: \(dict1)")
        print("Dict2: \(dict2)")

        // Merge
        dict1.merge(dict2) { (current, _) in current }
        print("After merge (dict1 keeps values): \(dict1)")

        // Merging with new dictionary
        let merged = dict1.merging(dict2) { _, new in new }
        print("Merging with dict2 values: \(merged)")

        // Filter
        let filtered = dict1.filter { $0.value > 2 }
        print("Filtered (> 2): \(filtered)")

        // Map values
        let squaredValues = dict1.mapValues { $0 * $0 }
        print("Squared values: \(squaredValues)")

        // Map keys
        let uppercasedKeys = dict1.mapKeys { $0.uppercased() }
        print("Uppercased keys: \(uppercasedKeys)")

        // Reduce
        let sum = dict1.reduce(0) { $0 + $1.value }
        print("Sum of values: \(sum)")

        // Grouping
        let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        let grouped = Dictionary(grouping: numbers, by: { $0 % 2 })
        print("Grouped by even/odd: \(grouped)")
    }
}

// 4. Dictionary Searching and Querying
class DictionarySearching {

    static func demonstrateSearching() {
        print("\n--- Dictionary Searching ---")

        let inventory = [
            "apples": 10,
            "bananas": 5,
            "oranges": 8,
            "pears": 12,
            "grapes": 3
        ]

        // Contains key
        print("Contains 'apples': \(inventory.keys.contains("apples"))")
        print("Contains 'mangos': \(inventory.keys.contains("mangos"))")

        // Contains value
        print("Contains value 10: \(inventory.values.contains(10))")

        // Find key for value
        if let keyFor10 = inventory.first(where: { $0.value == 10 })?.key {
            print("Key for value 10: \(keyFor10)")
        }

        // Filter keys by condition
        let lowStock = inventory.filter { $0.value < 5 }
        print("Low stock items: \(lowStock)")

        // Find all keys with specific condition
        let highStockKeys = inventory.filter { $0.value >= 10 }
            .map { $0.key }
        print("High stock items: \(highStockKeys)")

        // Min and Max values
        if let minItem = inventory.min(by: { $0.value < $1.value }) {
            print("Minimum quantity: \(minItem.key) - \(minItem.value)")
        }

        if let maxItem = inventory.max(by: { $0.value < $1.value }) {
            print("Maximum quantity: \(maxItem.key) - \(maxItem.value)")
        }

        // Count with condition
        let countBelow10 = inventory.values.filter { $0 < 10 }.count
        print("Items below 10: \(countBelow10)")
    }
}

// 5. Custom Hashable Types
class CustomHashable {

    struct Person: Hashable {
        let name: String
        let age: Int

        // Custom hash function
        func hash(into hasher: inout Hasher) {
            hasher.combine(name.lowercased())
            hasher.combine(age / 10) // Group by age decade
        }

        // Equality
        static func == (lhs: Person, rhs: Person) -> Bool {
            return lhs.name.lowercased() == rhs.name.lowercased() &&
                   lhs.age / 10 == rhs.age / 10
        }
    }

    static func demonstrateCustomHashable() {
        print("\n--- Custom Hashable Types ---")

        let people = [
            Person(name: "Alice", age: 25),
            Person(name: "Bob", age: 30),
            Person(name: "Charlie", age: 28),
            Person(name: "alice", age: 26) // Same hash as Alice
        ]

        // Create set with custom hashable
        let uniquePeople = Set(people)
        print("Unique people (custom hash): \(uniquePeople.count)")

        // Create dictionary
        var personData: [Person: String] = [:]
        for person in people {
            personData[person] = "\(person.name) is \(person.age)"
        }

        print("Person data count: \(personData.count)")
    }

    enum Color: Int, Hashable {
        case red, green, blue
    }

    struct Fruit: Hashable {
        let name: String
        let color: Color
    }

    static func demonstrateEnumDictionary() {
        print("\n--- Enum Keys ---")

        let colorNames: [Color: String] = [
            .red: "Red",
            .green: "Green",
            .blue: "Blue"
        ]

        for (color, name) in colorNames {
            print("  \(color): \(name)")
        }
    }
}

// 6. Nested Dictionaries
class NestedDictionaries {

    static func demonstrateNested() {
        print("\n--- Nested Dictionaries ---")

        // Create nested structure
        var company: [String: [String: Any]] = [:]

        company["engineering"] = [
            "employees": 50,
            "budget": 1000000,
            "location": "Building A"
        ]

        company["marketing"] = [
            "employees": 20,
            "budget": 500000,
            "location": "Building B"
        ]

        print("Company structure: \(company)")

        // Access nested values
        if let engineering = company["engineering"],
           let employees = engineering["employees"] as? Int {
            print("Engineering employees: \(employees)")
        }

        // Update nested
        company["engineering"]?["budget"] = 1200000
        print("After update: \(company)")

        // Iterate nested
        print("\nDepartments:")
        for (dept, info) in company {
            let employees = info["employees"] ?? 0
            let budget = info["budget"] ?? 0
            print("  \(dept): \(employees) employees, budget: \(budget)")
        }
    }
}

// 7. Dictionary as Cache
class DictionaryCache {

    private var cache: [String: Any] = [:]
    private var accessOrder: [String] = []

    func get<T>(_ key: String) -> T? {
        if let value = cache[key] as? T {
            // Update access order
            if let index = accessOrder.firstIndex(of: key) {
                accessOrder.remove(at: index)
            }
            accessOrder.append(key)
            return value
        }
        return nil
    }

    func set<T>(_ key: String, value: T) {
        cache[key] = value
        if !accessOrder.contains(key) {
            accessOrder.append(key)
        }
    }

    func remove(_ key: String) {
        cache[key] = nil
        if let index = accessOrder.firstIndex(of: key) {
            accessOrder.remove(at: index)
        }
    }

    func clear() {
        cache.removeAll()
        accessOrder.removeAll()
    }

    // LRU eviction
    func evictLRU(maxSize: Int) {
        while cache.count > maxSize {
            if let oldest = accessOrder.first {
                remove(oldest)
                print("Evicted: \(oldest)")
            }
        }
    }

    static func demonstrateCache() {
        print("\n--- Dictionary as Cache ---")

        let cache = DictionaryCache()

        // Set values
        cache.set("user:1", value: "Alice")
        cache.set("user:2", value: "Bob")
        cache.set("user:3", value: "Charlie")

        // Get values
        if let user1: String = cache.get("user:1") {
            print("User 1: \(user1)")
        }

        // Access to update LRU order
        _ = cache.get("user:1")
        _ = cache.get("user:2")

        // Evict
        cache.evictLRU(maxSize: 2)
    }
}

// 8. Dictionary Performance
class DictionaryPerformance {

    static func demonstratePerformance() {
        print("\n--- Dictionary Performance ---")

        // Pre-allocate capacity
        var dict = [String: Int]()
        dict.reserveCapacity(1000)
        print("Reserved capacity: \(dict.capacity)")

        // Bulk operations
        let pairs = (1...100).map { (key: "key\($0)", value: $0) }
        let bulkDict = Dictionary(uniqueKeysWithValues: pairs)
        print("Bulk created dict count: \(bulkDict.count)")

        // Lookup performance
        let largeDict = Dictionary(uniqueKeysWithValues: (1...100000).map { ("key\($0)", $0) })

        let start = Date()
        _ = largeDict["key50000"]
        let elapsed = Date().timeIntervalSince(start)
        print("Lookup time: \(elapsed * 1000)ms")
    }
}

// 9. Thread-Safe Dictionary
class ThreadSafeDictionary {

    private var dictionary: [String: Any] = [:]
    private let lock = NSLock()

    func setValue(_ value: Any, forKey key: String) {
        lock.lock()
        defer { lock.unlock() }
        dictionary[key] = value
    }

    func getValue(forKey key: String) -> Any? {
        lock.lock()
        defer { lock.unlock() }
        return dictionary[key]
    }

    func removeValue(forKey key: String) {
        lock.lock()
        defer { lock.unlock() }
        dictionary[key] = nil
    }

    static func demonstrateThreadSafe() {
        print("\n--- Thread-Safe Dictionary ---")

        let safeDict = ThreadSafeDictionary()

        // Concurrent writes
        let group = DispatchGroup()

        for i in 1...10 {
            group.enter()
            DispatchQueue.global().async {
                safeDict.setValue("value\(i)", forKey: "key\(i)")
                group.leave()
            }
        }

        group.wait()
        print("Thread-safe writes completed")

        // Read
        if let value = safeDict.getValue(forKey: "key5") {
            print("Retrieved: \(value)")
        }
    }
}

// 10. Dictionary Utilities
class DictionaryUtilities {

    static func demonstrateUtilities() {
        print("\n--- Dictionary Utilities ---")

        var dict = ["a": 1, "b": 2, "c": 3, "d": 4, "e": 5]

        // Count
        print("Count: \(dict.count)")

        // Is empty
        print("Is empty: \(dict.isEmpty)")

        // Keys array
        print("Keys: \(dict.keys.sorted())")

        // Values array
        print("Values: \(dict.values.sorted())")

        // Random key
        if let randomKey = dict.keys.randomElement() {
            print("Random key: \(randomKey)")
        }

        // Swap
        dict.swapAt("a", "b") // Note: Not directly available, need to swap values
        let temp = dict["a"]
        dict["a"] = dict["b"]
        dict["b"] = temp
        print("After swap: \(dict)")

        // Check all satisfy condition
        let allGreaterThanZero = dict.allSatisfy { $0.value > 0 }
        print("All > 0: \(allGreaterThanZero)")

        // Check any satisfies condition
        let anyGreaterThanThree = dict.contains { $0.value > 3 }
        print("Any > 3: \(anyGreaterThanThree)")
    }
}

// Main demonstration
func demonstrateHashTables() {
    print("=== macOS Swift Hash Table Examples ===")

    DictionaryBasics.demonstrateBasics()
    DictionaryIteration.demonstrateIteration()
    DictionaryOperations.demonstrateOperations()
    DictionarySearching.demonstrateSearching()
    CustomHashable.demonstrateCustomHashable()
    CustomHashable.demonstrateEnumDictionary()
    NestedDictionaries.demonstrateNested()
    DictionaryCache.demonstrateCache()
    DictionaryPerformance.demonstratePerformance()
    ThreadSafeDictionary.demonstrateThreadSafe()
    DictionaryUtilities.demonstrateUtilities()

    print("\n=== All Hash Table Examples Completed ===")
}

// Run demonstration
demonstrateHashTables()

💻 Liste Chaînée swift

🟡 intermediate ⭐⭐⭐⭐

Implémenter des listes chaînées simples et doubles avec des opérations courantes et des algorithmes

⏱️ 40 min 🏷️ swift, macos, data structures, linked list
Prerequisites: Intermediate Swift, Classes, Memory management
// macOS Swift Linked List Examples
// Custom implementation using classes

import Foundation

// 1. Singly Linked List Node
class ListNode<T> {
    var value: T
    var next: ListNode<T>?

    init(_ value: T) {
        self.value = value
        self.next = nil
    }
}

// 2. Singly Linked List
class LinkedList<T>: CustomStringConvertible {

    private var head: ListNode<T>?
    private var tail: ListNode<T>?

    var isEmpty: Bool {
        return head == nil
    }

    var first: ListNode<T>? {
        return head
    }

    var last: ListNode<T>? {
        return tail
    }

    // Append to end
    func append(_ value: T) {
        let newNode = ListNode(value)

        if let tailNode = tail {
            tailNode.next = newNode
        } else {
            head = newNode
        }

        tail = newNode
    }

    // Insert at beginning
    func prepend(_ value: T) {
        let newNode = ListNode(value)
        newNode.next = head
        head = newNode

        if tail == nil {
            tail = newNode
        }
    }

    // Insert at index
    func insert(_ value: T, at index: Int) {
        guard index > 0 else {
            prepend(value)
            return
        }

        let newNode = ListNode(value)
        var current = head
        var currentIndex = 0

        while current != nil && currentIndex < index - 1 {
            current = current?.next
            currentIndex += 1
        }

        newNode.next = current?.next
        current?.next = newNode

        if newNode.next == nil {
            tail = newNode
        }
    }

    // Remove first
    func removeFirst() -> T? {
        guard let headNode = head else { return nil }

        head = headNode.next

        if head == nil {
            tail = nil
        }

        return headNode.value
    }

    // Remove last
    func removeLast() -> T? {
        guard let headNode = head else { return nil }

        if head === tail {
            head = nil
            tail = nil
            return headNode.value
        }

        var current = head
        while current?.next !== tail {
            current = current?.next
        }

        let value = tail?.value
        tail = current
        tail?.next = nil

        return value
    }

    // Remove at index
    func remove(at index: Int) -> T? {
        guard index >= 0 else { return nil }

        if index == 0 {
            return removeFirst()
        }

        var current = head
        var currentIndex = 0

        while current != nil && currentIndex < index - 1 {
            current = current?.next
            currentIndex += 1
        }

        guard let nodeToRemove = current?.next else { return nil }

        current?.next = nodeToRemove.next

        if nodeToRemove === tail {
            tail = current
        }

        return nodeToRemove.value
    }

    // Find value
    func find(_ value: T) -> ListNode<T>? where T: Equatable {
        var current = head

        while current != nil {
            if current?.value == value {
                return current
            }
            current = current?.next
        }

        return nil
    }

    // Contains
    func contains(_ value: T) -> Bool where T: Equatable {
        return find(value) != nil
    }

    // Count
    var count: Int {
        var count = 0
        var current = head

        while current != nil {
            count += 1
            current = current?.next
        }

        return count
    }

    // Reverse
    func reverse() {
        var previous: ListNode<T>? = nil
        var current = head

        tail = head

        while current != nil {
            let next = current?.next
            current?.next = previous
            previous = current
            current = next
        }

        head = previous
    }

    // Array conversion
    func toArray() -> [T] {
        var array: [T] = []
        var current = head

        while current != nil {
            array.append(current!.value)
            current = current?.next
        }

        return array
    }

    // Description
    var description: String {
        var array = toArray()
        return array.map { String(describing: $0) }.joined(separator: " -> ")
    }

    // Print list
    func printList() {
        print(description)
    }
}

// 3. Doubly Linked List Node
class DoublyListNode<T> {
    var value: T
    var next: DoublyListNode<T>?
    weak var previous: DoublyListNode<T>?

    init(_ value: T) {
        self.value = value
    }
}

// 4. Doubly Linked List
class DoublyLinkedList<T>: CustomStringConvertible {

    private var head: DoublyListNode<T>?
    private var tail: DoublyListNode<T>?

    var isEmpty: Bool {
        return head == nil
    }

    var first: DoublyListNode<T>? {
        return head
    }

    var last: DoublyListNode<T>? {
        return tail
    }

    func append(_ value: T) {
        let newNode = DoublyListNode(value)

        if let tailNode = tail {
            tailNode.next = newNode
            newNode.previous = tailNode
        } else {
            head = newNode
        }

        tail = newNode
    }

    func prepend(_ value: T) {
        let newNode = DoublyListNode(value)
        newNode.next = head
        head?.previous = newNode
        head = newNode

        if tail == nil {
            tail = newNode
        }
    }

    func remove(_ node: DoublyListNode<T>) -> T {
        let prev = node.previous
        let next = node.next

        if prev === nil {
            head = next
        } else {
            prev?.next = next
        }

        if next === nil {
            tail = prev
        } else {
            next?.previous = prev
        }

        return node.value
    }

    func removeFirst() -> T? {
        guard let headNode = head else { return nil }
        return remove(headNode)
    }

    func removeLast() -> T? {
        guard let tailNode = tail else { return nil }
        return remove(tailNode)
    }

    var count: Int {
        var count = 0
        var current = head

        while current != nil {
            count += 1
            current = current?.next
        }

        return count
    }

    var description: String {
        var array: [T] = []
        var current = head

        while current != nil {
            array.append(current!.value)
            current = current?.next
        }

        return array.map { String(describing: $0) }.joined(separator: " <-> ")
    }

    // Reverse iteration
    func reversed() -> [T] {
        var array: [T] = []
        var current = tail

        while current != nil {
            array.append(current!.value)
            current = current?.previous
        }

        return array
    }
}

// 5. Linked List Algorithms
class LinkedListAlgorithms {

    // Find middle node
    static func findMiddle<T>(_ list: LinkedList<T>) -> ListNode<T>? {
        var slow = list.first
        var fast = list.first

        while fast?.next != nil && fast?.next?.next != nil {
            slow = slow?.next
            fast = fast?.next?.next
        }

        return slow
    }

    // Detect cycle
    static func hasCycle<T>(_ head: ListNode<T>?) -> Bool {
        var slow = head
        var fast = head

        while fast != nil && fast?.next != nil {
            slow = slow?.next
            fast = fast?.next?.next

            if slow === fast {
                return true
            }
        }

        return false
    }

    // Merge two sorted lists
    static func mergeSortedLists<T: Comparable>(_ list1: LinkedList<T>, _ list2: LinkedList<T>) -> LinkedList<T> {
        let result = LinkedList<T>()

        var current1 = list1.first
        var current2 = list2.first

        while current1 != nil && current2 != nil {
            if current1!.value <= current2!.value {
                result.append(current1!.value)
                current1 = current1?.next
            } else {
                result.append(current2!.value)
                current2 = current2?.next
            }
        }

        while current1 != nil {
            result.append(current1!.value)
            current1 = current1?.next
        }

        while current2 != nil {
            result.append(current2!.value)
            current2 = current2?.next
        }

        return result
    }

    // Remove duplicates
    static func removeDuplicates<T: Equatable>(_ list: LinkedList<T>) {
        var seen: Set<T> = []
        var current = list.first

        while current != nil {
            if seen.contains(current!.value) {
                // Skip duplicate (in real implementation, would remove node)
            } else {
                seen.insert(current!.value)
            }
            current = current?.next
        }
    }

    // Get nth node from end
    static func getNthFromEnd<T>(_ list: LinkedList<T>, _ n: Int) -> ListNode<T>? {
        var lead = list.first
        var follow = list.first

        // Move lead n steps ahead
        for _ in 0..<n {
            if lead == nil { return nil }
            lead = lead?.next
        }

        // Move both until lead reaches end
        while lead != nil {
            lead = lead?.next
            follow = follow?.next
        }

        return follow
    }

    // Partition list
    static func partition<T: Comparable>(_ list: LinkedList<T>, pivot: T) -> LinkedList<T> {
        let less = LinkedList<T>()
        let greaterOrEqual = LinkedList<T>()

        var current = list.first

        while current != nil {
            if current!.value < pivot {
                less.append(current!.value)
            } else {
                greaterOrEqual.append(current!.value)
            }
            current = current?.next
        }

        // Merge lists
        let result = LinkedList<T>()
        var currentLess = less.first
        var currentGreater = greaterOrEqual.first

        while currentLess != nil {
            result.append(currentLess!.value)
            currentLess = currentLess?.next
        }

        while currentGreater != nil {
            result.append(currentGreater!.value)
            currentGreater = currentGreater?.next
        }

        return result
    }
}

// 6. Linked List Utilities
class LinkedListUtilities {

    static func printReversed<T>(_ list: LinkedList<T>) {
        print("Print reversed:")
        var array = list.toArray()
        for i in stride(from: array.count - 1, through: 0, by: -1) {
            print("  \(array[i])", terminator: " -> ")
        }
        print("nil")
    }

    static func compareLists<T: Equatable>(_ list1: LinkedList<T>, _ list2: LinkedList<T>) -> Bool {
        var current1 = list1.first
        var current2 = list2.first

        while current1 != nil && current2 != nil {
            if current1!.value != current2!.value {
                return false
            }
            current1 = current1?.next
            current2 = current2?.next
        }

        return current1 == nil && current2 == nil
    }

    static func isPalindrome<T: Equatable>(_ list: LinkedList<T>) -> Bool {
        let array = list.toArray()
        return array == array.reversed() as [T]
    }
}

// 7. Stack using Linked List
class LinkedListStack<T> {

    private var list = LinkedList<T>()

    var isEmpty: Bool {
        return list.isEmpty
    }

    var count: Int {
        return list.count
    }

    func push(_ value: T) {
        list.prepend(value)
    }

    func pop() -> T? {
        return list.removeFirst()
    }

    func peek() -> T? {
        return list.first?.value
    }
}

// 8. Queue using Linked List
class LinkedListQueue<T> {

    private var list = LinkedList<T>()

    var isEmpty: Bool {
        return list.isEmpty
    }

    var count: Int {
        return list.count
    }

    func enqueue(_ value: T) {
        list.append(value)
    }

    func dequeue() -> T? {
        return list.removeFirst()
    }

    func peek() -> T? {
        return list.first?.value
    }
}

// Main demonstration
func demonstrateLinkedLists() {
    print("=== macOS Swift Linked List Examples ===")

    // 1. Singly Linked List
    print("\n--- Singly Linked List ---")
    let list = LinkedList<Int>()
    list.append(1)
    list.append(2)
    list.append(3)
    list.prepend(0)
    list.insert(99, at: 2)

    print("List: \(list)")
    print("Count: \(list.count)")
    print("Contains 2: \(list.contains(2))")

    list.reverse()
    print("After reverse: \(list)")

    _ = list.removeFirst()
    _ = list.removeLast()
    _ = list.remove(at: 1)
    print("After removals: \(list)")

    // 2. Doubly Linked List
    print("\n--- Doubly Linked List ---")
    let dList = DoublyLinkedList<String>()
    dList.append("First")
    dList.append("Second")
    dList.append("Third")
    dList.prepend("Zero")

    print("Forward: \(dList)")
    print("Backward: \(dList.reversed())")

    // 3. Algorithms
    print("\n--- Linked List Algorithms ---")

    let numberList = LinkedList<Int>()
    for i in 1...10 {
        numberList.append(i)
    }

    if let middle = LinkedListAlgorithms.findMiddle(numberList) {
        print("Middle node value: \(middle.value)")
    }

    if let nodeFromEnd = LinkedListAlgorithms.getNthFromEnd(numberList, 3) {
        print("3rd from end: \(nodeFromEnd.value)")
    }

    // Merge sorted lists
    let list1 = LinkedList<Int>()
    list1.append(1)
    list1.append(3)
    list1.append(5)

    let list2 = LinkedList<Int>()
    list2.append(2)
    list2.append(4)
    list2.append(6)

    let merged = LinkedListAlgorithms.mergeSortedLists(list1, list2)
    print("Merged sorted: \(merged)")

    // 4. Stack and Queue
    print("\n--- Stack using Linked List ---")
    let stack = LinkedListStack<Int>()
    stack.push(10)
    stack.push(20)
    stack.push(30)

    print("Stack count: \(stack.count)")
    print("Pop: \(stack.pop() ?? 0)")
    print("Peek: \(stack.peek() ?? 0)")

    print("\n--- Queue using Linked List ---")
    let queue = LinkedListQueue<Int>()
    queue.enqueue(100)
    queue.enqueue(200)
    queue.enqueue(300)

    print("Queue count: \(queue.count)")
    print("Dequeue: \(queue.dequeue() ?? 0)")
    print("Peek: \(queue.peek() ?? 0)")

    // 5. Utilities
    print("\n--- Linked List Utilities ---")
    let testList = LinkedList<Int>()
    for i in 1...5 {
        testList.append(i)
    }

    LinkedListUtilities.printReversed(testList)

    let palindromeList = LinkedList<Int>()
    [1, 2, 3, 2, 1].forEach { palindromeList.append($0) }
    print("Is palindrome: \(LinkedListUtilities.isPalindrome(palindromeList))")

    print("\n=== All Linked List Examples Completed ===")
}

// Run demonstration
demonstrateLinkedLists()