【问题标题】:Replicating Array.reduce() method复制 Array.reduce() 方法
【发布时间】:2018-07-05 13:13:47
【问题描述】:

我试图在我的自定义类中复制 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, +))")

问题是我必须一次用一种特定类型( Int 或 String 或 Double 等)定义我的 perform() 函数。我正在尝试创建我的函数以使用任何类型,就像 reduce() 函数一样。

我无法理解如何在我的类中定义 Result 类型,然后在我的函数中使用它!!

我知道 Result 类型不是 swift 标准库的一部分。

【问题讨论】:

  • 不相关,但 getInstance() 方法是 objective-c-ish 且毫无意义。只需写static let instance = MyArray()(称为MyArray.instance)并删除整个getInstance() 方法。 static 变量在 Swift 中默认是惰性创建的。

标签: swift closures higher-order-functions


【解决方案1】:

标准的reduce 函数使用泛型。请参阅 Swift 书籍中的 Generics 章节。

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

它有两种通用类型:ResultElementElement 来自集合中值的类型,Result 来自缩减值的结果类型。

所以您的第一步是在您自己的perform 函数中使用相同的签名。

但是这样做你会发现你现在需要让你的MyArray类也基于一个泛型而不是被硬编码为只使用Int

在尝试这样做时,您会发现您不能将MyArray 定义为通用的并同时支持单例模式。所以你需要删除instancegetIntance()

最终结果变成:

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

【讨论】:

  • 非常感谢@rmaddy。这正是我一直在寻找的。但我无法理解的是标准库中已经定义了 Result 类型,还是我们必须在代码中的某个地方定义它??
  • Result 是用于泛型的任意名称。我本可以使用Etwwc(任何随机标识符)。请阅读我链接的泛型章节以了解。
  • 亲爱的@rmaddy,非常感谢您的宝贵建议。我现在正在阅读泛型章节,这似乎很有趣。目前我正在学习
  • 亲爱的@rmaddy,非常感谢您的宝贵建议。我现在正在阅读泛型章节,这似乎很有趣。目前我正在学习类型约束。但我的 MyArray 课程需要帮助。我在下面提供了一个指向我的自定义类的链接。您能否下载并查看为什么在按照您的建议实施“元素”后出现这些错误。老实说,我无法弄清楚如何纠正这些错误。您的帮助将不胜感激。 [dropbox.com/sh/hwymf97bih65cgi/AABxlxxyrPqH48l9oVsvnI4la?dl=0].
  • @vermau 如果您对新问题有新问题,请发布新问题。
猜你喜欢
  • 2014-08-06
  • 1970-01-01
  • 2020-04-28
  • 1970-01-01
  • 2020-02-16
  • 2017-11-06
  • 2023-03-13
  • 1970-01-01
  • 2021-10-27
相关资源
最近更新 更多