Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Consolidate

Build Status Docs SPM

Installation

Swift Package Manager

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

Usage Example

Using 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)
]

Using Closures

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)
]

Using Consolidatable Protocol

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)
    }
}

The above implementation would consolidate like this:

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)
]

Consolidate into single item (throws if unable to)

There may be times where you want to consolidate a collection of elements into a single element. For this, there exists the array extension consolidatedIntoSingle. It is functionally similar to the other consolidation methods, except its return type is of type Element rather than [Element]. This means that the collection has to be consolidatable to a single element. If the collection can't be consolidated to a single element, then the method will throw the error 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)
}

Whereas:

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)
]

About

🎳 Consolidates an array of Elements by KeyPath, Closure, or Conformance - Swift Micro Package

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages