合并

Build Status Docs SPM

安装

Swift Package Manager

dependencies: [
   .package(url: "https://github.com/SoftwareEngineerChris/Consolidate.git", from: "1.0.0")
]

使用示例

使用 KeyPath

let allTaxes = [
    TaxAmount(name: "Import Tax", amount: 3.00),
    TaxAmount(name: "Sales Tax", amount: 1.75),
    TaxAmount(name: "Import Tax", amount: 2.30)
]

let consolidatedTaxes = allTaxes.consolidated(by: \.name) {
    TaxAmount(tax: $0.name, amount: $0.amount + $1.amount)
}

// Would result in:

let consolidatedTaxes = [
    TaxAmount(name: "Import Tax", amount: 5.30),
    TaxAmount(name: "Sales Tax", amount: 4.10)
]

使用闭包

let allTaxes = [
    TaxAmount(name: "Import Tax", amount: 3.00),
    TaxAmount(name: "Sales Tax", amount: 1.75),
    TaxAmount(name: "Import Tax", amount: 2.30)
]

let consolidatedTaxes = allTaxes.consolidated(by: { $0.name == $1.name }) {
    TaxAmount(tax: $0.name, amount: $0.amount + $1.amount)
}

// Would result in:

 let consolidatedTaxes = [
    TaxAmount(name: "Import Tax", amount: 5.30),
    TaxAmount(name: "Sales Tax", amount: 4.10)
]

使用 Consolidatable 协议

struct TaxAmount: Consolidatable {

    let name: String
    let amount: Decimal

    var consolidationGroup: AnyHashable {
        return name
    }

    func consolidate(with other: Self) -> Self {
        return .init(name: name, amount: amount + other.amount)
    }
}

上述实现会像这样合并

let taxes = [
    TaxAmount(name: "Import Tax", amount: 3.00),
    TaxAmount(name: "Sales Tax", amount: 1.75),
    TaxAmount(name: "Import Tax", amount: 2.30)
].consolidated()

// Results in:

let taxes = [
    TaxAmount(name: "Import Tax", amount: 5.30),
    TaxAmount(name: "Sales Tax", amount: 4.10)
]

合并为单个项目(如果无法合并则抛出错误)

有时您可能希望将元素集合合并为单个元素。为此,存在数组扩展 consolidatedIntoSingle。它在功能上与其他合并方法类似,只是其返回类型是 Element 类型,而不是 [Element] 类型。这意味着集合必须可合并为单个元素。如果集合无法合并为单个元素,则该方法将抛出错误 ConsolidationError.couldNotBeConolidatedIntoSingleElement

let allTaxes = [
    TaxAmount(name: "Import Tax", amount: 3.00),
    TaxAmount(name: "Sales Tax", amount: 1.75),
    TaxAmount(name: "Import Tax", amount: 2.30)
]

// The line below would throw `ConsolidationError.couldNotBeConolidatedIntoSingleElement`,
// since the taxes can't be consolidated into a single tax when using the name key-path.

let consolidatedTax = try allTaxes.consolidatedIntoSingle(by: \.name) {
    TaxAmount(tax: $0.name, amount: $0.amount + $1.amount)
}

let allTaxes = [
    TaxAmount(name: "Import Tax", amount: 3.00),
    TaxAmount(name: "Import Tax", amount: 2.30)
]

let consolidatedTax = try allTaxes.consolidatedIntoSingle(by: \.name) {
    TaxAmount(tax: $0.name, amount: $0.amount + $1.amount)
}

// Since all taxes have the name "Import Tax", they can be consolidated into a single tax
// when using the name key-path. The result would be:

let consolidatedTax = [
    TaxAmount(name: "Import Tax", amount: 5.30)
]