合并具有相同 ID 的行 - SWIFT

时间:2020-12-21 17:00:17

标签: swift

我已经编辑并简化了我的问题。

这是我当前的数据。

struct Account{
        public let accId: String
        public let accName: String
        public let amount: Int
    }
    
let accounts = [
        Account(accId: "A", accName: "Account A", amount: 10),
        Account(accId: "A", accName: "Account A", amount: 4),
        Account(accId: "B", accName: "Account B", amount: 2),
        Account(accId: "C", accName: "Account C", amount: 3)
    ]

这就是我想要达到的目标。我想合并具有相同 accId 的行并求和。

let mergedAccounts = [
        Account(accId: "A", accName: "Account A", amount: 14),
        Account(accId: "B", accName: "Account B", amount: 2),
        Account(accId: "C", accName: "Account C", amount: 3)
    ]

我试过这个,但它只会将它们分组而不是合并它们。(@BJBeecher)

let dict = Dictionary(grouping: Budget, by: \.accId)

而且我也试过这个,它确实合并了它们,但它只会输出 [accId : amount],而忽略了 accName。

let sumAmountByAccount = selectedBudget.reduce(into: [:]) { (result, offer)  in
    result[offer.accId] = (result[offer.accId] ?? 0 ) + offer.amount}

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

感谢您更新问题。我要做的第一件事是将您的帐户元数据抽象为一种新类型并从那里开始。这是我得到的...

// model seperation by composition

struct Account : Hashable {
    let accId: String
    let accName: String
}

struct Order {
    let account : Account
    let amount: Int
}

struct AccountTotal {
    let account : Account
    let totalAmount: Int
}

// how to group and get totals

let seq = [Order]()

let dict = Dictionary(grouping: seq, by: \.account)

let accountTotals = dict.map { (account, orders) -> AccountTotal in
    // reduce orders to get total
    let totalAmount = orders.reduce(0) { total, order in total + order.amount }
    // return new account total
    return .init(account: account, totalAmount: totalAmount)
}

如果您有任何问题,请告诉我!

答案 1 :(得分:0)

如果你的 selectedBudgetAmount 有 Int 类型的数组,你可以这样使用

let amount = selectedBudgetAmount.reduce(0, +)

或者如果你是字符串类型的数组,那么你可以像这样使用

let amount = selectedBudgetAmount.reduce(0, { lastSum, currentData in
    lastSum + (Double(currentData) ?? 0.0) // <- Change Double type to as per your requirement. if needed.
})

或者如果您的数组是模型类型,那么您可以像这样使用

// Your Data Model
struct DataModel {
    var type: String
    var amount: Double
}
let amount = selectedBudgetAmount.reduce(0, { lastSum, currentData in
    lastSum + currentData.amount
})

答案 2 :(得分:0)

我不确定这是否是最有效的方法,但它有效。通过执行以下操作,我能够获得想要的结果:

  1. 我添加了不会更改的标准帐户详细信息。
let accountDetails = [
    AccDetailsModel(accId: "A", accName: "Account A"),
    AccDetailsModel(accId: "B", accName: "Account B"),
    AccDetailsModel(accId: "C", accName: "Account C")
]
  1. 按帐户汇总总金额
let dict = Dictionary(grouping: accounts, by: \.accId)
let sumAmountByAccount = accounts.reduce(into: [:]) { (result, offer)  in
    result[offer.accId] = (result[offer.accId] ?? 0 ) + offer.amount
}
  1. 然后执行以下操作以将总计与 accId 和 bankName 合并。
var mergedResult = [Account]()
var accountName = String()

for (key, value) in sumAmountByAccount {
    for data in accountDetails {
        if data.accId == key {
            accountName = data.accName
        }
    }
    mergedResult.append(Account.init(accId: key, accName: accountName, amount: value))
}
print(mergedResult)