我有一个 struct ,其中包含一组引用不同类型统计信息的属性.示例对象为:

class Stats {
    stats: [Stat]
}
struct Stat {
    id: UUID
    countA: Int
    countB: Int
    countC: Int
    totalAAttempts: Int
    totalBAttempts: Int
    totalCAttempts: Int
    ...
}

我正在用类中的一系列函数显示百分比.

class Stats {
    stats: [Stat]
    var countAPerc: Double {
        let totalA = stats.reduce(0) { total, stat in
            total + stat.countA
        }
        let totalAttemps = s.reduce(0) { total, stat in
            total + stat.totalAAttempts
        }
        return Double(totalA) / Double(totalAttempts)
    }
    var: countAPercDisplay: String {
        String(format: "%.1f", countAPerc * 100) + "%"
    }
    var countBPerc: Double {
        let totalB = stats.reduce(0) { total, stat in
            total + stat.countB
        }
        let totalAttemps = s.reduce(0) { total, stat in
            total + stat.totalBAttempts
        }
        return Double(totalB) / Double(totalAttempts)
    }
    var: countBPercDisplay: String {
        String(format: "%.1f", countBPerc * 100) + "%"
    }
    ...
}

是否可以将属性的名称指定为函数中的参数,以防止相同的代码被反复重写?类似于:

func summarizeProperty(_ countProperty: PROPERTYNAME1, _ totalProperty: PROPERTYNAME2) -> Double {
    let totalCount = stats.reduce(0) { total, stat in
        total + stat.PROPERTYNAME1
    }
    let totalAttemps = s.reduce(0) { total, stat in
        total + stat.PROPERTYNAME2
    }
    return Double(totalCount) / Double(totalAttempts)
}

func summarizedProperty(_ countProperty: PROPERTYNAME1, _ totalProperty: PROPERTYNAME2) -> String {
    let summarized = summarizeProperty(PROPERTYNAME1, PROPERTYNAME2)
    return String(format: "%.1f", summarized * 100) + "%"
}

然后叫它...

Text(summarizedProperty(countA, totalAAttempts))

提前谢谢你

推荐答案

您需要的工具是KeyPath:

func summarizeProperty(_ countProperty: KeyPath<Stat, Int>, _ totalProperty: KeyPath<Stat, Int>) -> Double {
    let totalCount = stats.reduce(0) { total, stat in
        total + stat[keyPath: countProperty]
    }
    let totalAttempts = stats.reduce(0) { total, stat in
        total + stat[keyPath: totalProperty]
    }
    return Double(totalCount) / Double(totalAttempts)
}

KeyPath<Stat, Int>是Stat上返回Int的属性.它是使用keyPath:下标访问的,通常使用\语法创建:

Stats().summarizeProperty(\.countA, \.totalAAttempts)

KeyPath是普通值,可以按如下方式传递:

func summarizedProperty(_ countProperty: KeyPath<Stat, Int>, _ totalProperty: KeyPath<Stat, Int>) -> String {
    let summarized = summarizeProperty(countProperty, totalProperty)
    return String(format: "%.1f", summarized * 100.0) + "%"
}

Swift相关问答推荐

在SwiftUI中使用自定义图像填充列表行的正确方法

如何在init()中使用setter/getters?

按SWIFT中每个ID的最大值进行筛选/排序

同时具有每个文本的标识符的文本组的可扩展性标识符

MacOS 13-如何使用SwiftUI创建Message.App设置工具栏?

在一行语句中比较Date.now的相等性是否安全

我需要一些关于 SwiftUI 动画的帮助

Swift数据关系

在表单中对齐文本框

为什么我的Swift app不能用xcodebuild构建,但是用XCode可以构建?

为什么我在我的 Swift iOS 应用程序项目中收到 Xcode 中的错误消息无法识别的 Select 器发送到类?

@Binding 在@StateObject 和 View 上被发布了两次?

ForEach within List:模式的好处?

RxSwift 事件触发了两次

使用 Swiftui 水平修剪 Shape()

如何使 SwiftUI Picker 换行文本

(SwiftLint)如果有正文,如何编写规则(可能是自定义),在{之后总是\n(换行)?

如何将使用\u{ea12}创建的 Swift 字符串转换回其十六进制值/字符串ea12?

哪些版本的 Xcode 支持哪些版本的 Swift?

将活动指示器 colored颜色 更改为黑色