Всем привет!

На интервью иногда просят реализовать одну из функций высшего порядка. Решил потренироваться в их самостоятельной реализации. Ниже представлен результат моих тренировок =)

Иногда бывает легче реализовать функцию конкретного типа, а затем сделать её универсальной (Generic). Такого подхода я и буду придерживаться в примерах, приведенных ниже.

Все функции написаны в расширении массива ( extension Array)

Reduce

extension Array {
    func customIntReduce(res: Int, handler:(Int, Int) -> Int) -> Int {
        var result = res
        for elem in self {
            result = handler(result, elem as! Int)
        }
        return result
    }
    
    func customReduce<T, U>(res: T, handler:(T, U) -> T) -> T {
        var result = res
        for elem in self {
            result = handler(result, elem as! U)
        }
        return result
    }
}

print([1, 2, 3].customIntReduce(res: 0) { $0 + $1 })
print([1, 2, 3].customReduce(res: 0) { $0 + $1 })

Filter

  func customIntFilter(handler: (Int) -> Bool) -> [Int] {
        var filteredArray: [Int] = []
        
        for element in self {
            if handler(element as! Int) {
                filteredArray.append(element as! Int)
            }
        }
        return filteredArray
    }
    
    func customFilter(handler: (Element) -> Bool) -> [Element] {
        var filteredArray: [Element] = []
        for element in self {
            if handler(element) {
                filteredArray.append(element)
            }
        }
        return filteredArray
    }

    print([1, 2, 3, 4, 5].customIntFilter{ $0 > 2})
    print([1, 2, 3, 4, 5].customFilter{ $0 > 2})

Map

 func customIntMap(handler: (Int) -> Any) -> [Any] {
        var mapedArray:[Any] = []
        for elem in self {
            let mapedValue = handler(elem as! Int)
            mapedArray.append(mapedValue)
        }
        return mapedArray
    }
    
    func customMap<T>(handler: (Element) -> T) -> [T] {
        var mapedArray: [T] = []
        for elem in self {
            let mapedValue = handler(elem)
            mapedArray.append(mapedValue)
        }
        return mapedArray
    }

    print([1, 2, 3].customIntMap{ "\($0 * $0)" })
    print([1, 2, 3].customMap{ "\($0 * $0)" })

Compact Map

func customStringCompactMap(_ handler: (String) -> Any?) -> [Any] {
        var mapedArray: [Any] = []
        for elem in self {
            if let mapedValue = handler(elem as! String) {
                mapedArray.append(mapedValue)
            }
        }
        return mapedArray
    }
    
    func customCompactMap<T>(handler: (Element) -> T?) -> [T] {
        var mapedArray: [T] = []
        for elem in self {
            if let mapedValue = handler(elem) {
                mapedArray.append(mapedValue)
            }
        }
        return mapedArray
    }

    print(["1", "two", "3"].customStringCompactMap{ Int($0) })
    print(["1", "two", "3"].customCompactMap{ Int($0) })

Flat Map

 func customIntFlatMap(handler: ([Int]) -> Any) -> [Any] {
        var mappedArray: [Any] = []
        forEach {
            mappedArray += handler($0 as! [Int]) as! Array<Any>
        }
        return mappedArray
    }


    func customFlatMap<T>(handler: (Element) -> [T]) -> [T] {
        var mappedArray: [T] = []
        forEach {
            mappedArray += handler($0)
        }
        return mappedArray
    }


    let arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
        
    let mapped = arr.customIntFlatMap{ $0 }
    print(mapped)
        
    let mapped2 = arr.customFlatMap{ $0 }
    print(mapped2)

Надеюсь примеры помогут кому-то лучше подготовиться к собеседованию, а кому-то лучше разобраться в дженериках.

Комментарии (0)