Menu
Coddy logo textTech

Orden superior personalizado

Parte de la sección Lógica y Flujo del Journey de Swift de Coddy — lección 42 de 56.

Ahora puedes escribir tus propias funciones de orden superior y encajarán perfectamente junto a map y filter. La estructura es siempre la misma: toma un parámetro de clausura, llámalo dentro del bucle y devuelve el resultado.

extension Array {
    func myMap<T>(_ transform: (Element) -> T) -> [T] {
        var result: [T] = []
        for item in self {
            result.append(transform(item))
        }
        return result
    }
}

[1, 2, 3].myMap { $0 * 10 }       // [10, 20, 30]

Si las extensiones te parecen demasiado, escribe una función libre en su lugar, la idea es la misma:

func count<T>(_ items: [T], where predicate: (T) -> Bool) -> Int {
    var n = 0
    for item in items where predicate(item) {
        n += 1
    }
    return n
}

Una vez que puedes pasar closures, la biblioteca estándar deja de parecer magia y comienza a parecer un conjunto de patrones que podrías escribir tú mismo.

challenge icon

Desafío

Intermedio

Escribe una función libre partition(_ items: [Int], by predicate: (Int) -> Bool) -> ([Int], [Int]) que recorra el array una vez y devuelva una tupla (matched, rest): los elementos que cumplieron con el predicado y el resto, ambos en su orden original.

Lee dos líneas: un entero min, luego una lista de enteros separados por comas. Usa tu función partition con un predicado que verifique n > min. Imprime:

  1. matched: <...>
  2. rest: <...>

Cada lista unida con , (o vacía cuando no haya nada que imprimir).

Para la entrada 5 / 2,7,3,8,5, la salida es:

matched: 7,8
rest: 2,3,5

Hoja de referencia

Las funciones de orden superior siguen un patrón consistente: aceptar un closure, llamarlo en un bucle, devolver el resultado.

Como una extensión:

extension Array {
    func myMap<T>(_ transform: (Element) -> T) -> [T] {
        var result: [T] = []
        for item in self {
            result.append(transform(item))
        }
        return result
    }
}
[1, 2, 3].myMap { $0 * 10 }  // [10, 20, 30]

Como una función libre:

func count<T>(_ items: [T], where predicate: (T) -> Bool) -> Int {
    var n = 0
    for item in items where predicate(item) {
        n += 1
    }
    return n
}

Una función partition que devuelve una tupla de elementos coincidentes y no coincidentes:

func partition(_ items: [Int], by predicate: (Int) -> Bool) -> ([Int], [Int]) {
    var matched: [Int] = []
    var rest: [Int] = []
    for item in items {
        if predicate(item) { matched.append(item) }
        else { rest.append(item) }
    }
    return (matched, rest)
}

Pruébalo tú mismo

let min = Int(readLine()!)!
let nums = readLine()!.components(separatedBy: ",").map { Int($0)! }

// TODO: partition(_:by:) -> ([Int], [Int]); imprimir los que coinciden y el resto
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Lógica y Flujo