Репликация метода Array.reduce () - PullRequest
0 голосов
/ 05 июля 2018

Я пытаюсь скопировать метод Array.reduce() в моем пользовательском классе и понял, что он использует Result как тип. Просто не мог понять, что тип Result был создан как Enum или это что-то еще.

import Foundation

public class MyArray {
    private var arr: [Int] = []
    internal static var instance: MyArray?

    private init() {}

    public static func getInstance() -> MyArray {
        if self.instance == nil {
            self.instance = MyArray()
        }
        return self.instance!
    }

    public func insert(value val: Int) {
        arr.append(val)
    }

    /*************** Custom reduce like function ***************/

    public func perform(_ initialResult: Int, _ nextPartialResult: (Int, Int) -> Int) -> Int {
        var result = initialResult

        for element in arr {
            result = nextPartialResult(result, element)  // calling the closure
        }
        return result
    }
}

Теперь доступ к классу MyArray извне

var arr1 = MyArray.getInstance()
arr1.insert(value: 1)
arr1.insert(value: 2)
arr1.insert(value: 4)
arr1.insert(value: 3)
arr1.insert(value: 2)
arr1.insert(value: 5)
arr1.insert(value: 2)
arr1.insert(value: 2)

//  :Complex calculations left for user to implement
var result = arr1.perform(0) {
    return $0 + ( $1 * $1)
}
print("Complex calculation in elements of MEMBER array of arr1: \(result)")

//  :Just another way of writing the above closure
result = arr1.perform(0) { (result, num1) -> Int in
    return result + ( num1 * num1)
}
print("Complex calculation in elements of MEMBER array of hello arr1: \(result)")

//  :Simple calculations
print("Factorial of elements in MEMBER array of arr1: \(arr1.perform(1, *))")
print("Sum of elements in MEMBER array of arr1: \(arr1.perform(0, +))")

Проблема в том, что я должен определять свою функцию execute () по одному конкретному типу за раз (Int или String или Double и т. Д.). Я пытаюсь создать свою функцию для работы с любым типом, например, функцией redu ().

Я не могу понять, как определить тип результата в моем классе, а затем использовать его в своей функции !!

Я понимаю, что тип результата не является частью стандартной библиотеки в swift.

1 Ответ

0 голосов
/ 06 июля 2018

Стандартная функция reduce использует дженерики. См. Главу Generics в книге Swift.

func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result

Имеет два общих типа: Result и Element. Element исходит от типа значений в коллекции, а Result - от типа результата уменьшенного значения.

Итак, ваш первый шаг - использовать идентичную подпись в вашей собственной функции perform.

Но при этом вы обнаружите, что теперь вам нужно сделать свой класс MyArray также основанным на универсальном, а не жестко закодированном для работы только с Int.

И, пытаясь сделать это, вы обнаружите, что вы не можете определить MyArray как универсальный и одновременно поддерживать шаблон синглтона. Таким образом, вам нужно удалить instance и getIntance().

Конечный результат становится:

public class MyArray<Element> {
    private var arr: [Element] = []

    public init() {}

    public func insert(value val: Element) {
        arr.append(val)
    }

    /*************** Custom reduce like function ***************/

    public func perform<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) -> Result) -> Result {
        var result = initialResult

        for element in arr {
            result = nextPartialResult(result, element)
        }

        return result
    }
}

С этим, ваш первый пример становится:

var arr1 = MyArray<Int>()
arr1.insert(value: 1)
arr1.insert(value: 2)
arr1.insert(value: 4)
arr1.insert(value: 3)
arr1.insert(value: 2)
arr1.insert(value: 5)
arr1.insert(value: 2)
arr1.insert(value: 2)

//  :Complex calculations left for user to implement
var result = arr1.perform(0) {
    return $0 + ( $1 * $1)
}
print(result)

И это выводит желаемый результат 67.

В конце концов, это работает, но если вы заметите, нет никакого смысла в этом MyArray классе (кроме учебного упражнения). Просто используйте Array.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...