有没有有效的方法来合并对象数组?我有一个模型[sales]
,它有saleAmount, soldBy
。可能有多个由不同客户出售的商品。所以我想要的是,如果说,例如ABC出售的物品,那么我想对ABC出售的saleAmount求和。下面是一个示例。
class Sale {
var soldBy : String = ""
var saleAmount : Double = 0.00
}
var sales : [sale] = [sale]()
sales array contains:
[
["ABC", 1200.34],
["ABC", 999.34],
["ABC", 3499.99],
["DEF", 333.32],
["DEF", 778.12]
]
Expected output :
[["ABC", 5699.67],
["DEF" , 1111.44]]
答案 0 :(得分:2)
具有:
struct Sales {
let name: String
let amount: Float
init(name: String, amount: Float) {
self.name = name
self.amount = amount
}
}
我将添加:
extension Sales {
init(withSales initialSales: Sales, otherSale: Sales) {
self.init(name: initialSales.name, amount: initialSales.amount + otherSale.amount)
}
}
我将使用reduce(into:_:)
:
let sales: [Sales] = [Sales(name: "ABC", amount: 1200.34),
Sales(name: "ABC", amount: 999.34),
Sales(name: "ABC", amount: 3499.99),
Sales(name: "DEF", amount: 333.32),
Sales(name: "DEF", amount: 778.12)]
let reducedSale = sales.reduce(into: [Sales]()) { (currentResult, current) in
if let existingSalesIndex = currentResult.firstIndex(where: { $0.name == current.name }) {
let existingSale = currentResult[existingSalesIndex]
currentResult[existingSalesIndex] = Sales(withSales: existingSale, otherSale: current)
} else {
currentResult.append(current)
}
}
print("reducedSales: \(reducedSales: [AppName.Sales(name: "ABC", amount: 5699.67), AppName.Sales(name: "DEF", amount: 1111.44)])
由于使用了类,因此可以避免方便的初始化,而只需添加金额即可。
答案 1 :(得分:2)
销售类别:
class Sale{
var soldBy:String
var amount:Double
init(soldBy:String, amount:Double) {
self.soldBy = soldBy
self.amount = amount
}
}
计算输出:
let output = sales.reduce([String:Double]()) { (result, sale) -> [String:Double] in
var result = result
result[sale.soldBy, default: 0.0] += sale.amount
return result
}
参考: https://developer.apple.com/documentation/swift/dictionary/2925471-reduce
答案 2 :(得分:1)
您可以根据销售创建一系列键/值对,然后
使用Dictionary(_:uniquingKeysWith:)
用唯一键和总和创建字典
相应的值:
struct Sale {
let soldBy: String
let saleAmount: Double
}
let sales = [
Sale(soldBy: "ABC", saleAmount: 1200.34),
Sale(soldBy: "ABC", saleAmount: 999.34),
Sale(soldBy: "ABC", saleAmount: 3499.99),
Sale(soldBy: "DEF", saleAmount: 333.32),
Sale(soldBy: "DEF", saleAmount: 778.12),
]
let sums = Dictionary(sales.map { ($0.soldBy, $0.saleAmount) },
uniquingKeysWith: { $0 + $1 })
print(sums)
// ["ABC": 5699.67, "DEF": 1111.44]
然后您可以根据字典创建一系列销售:
let sumSales = sums.map { Sale(soldBy: $0.key, saleAmount: $0.value) }
print(sumSales)
// [Sale(soldBy: "ABC", saleAmount: 5699.67), Sale(soldBy: "DEF", saleAmount: 1111.44)]
出于演示目的,我假设Sale
是结构。
答案 3 :(得分:1)
您可以使用Dictionary(grouping:by:)
:
let groupedSales: [Sale] = Dictionary(grouping: sales) { $0.soldBy }
.lazy
.map { element in
let sum = element.value.lazy.map { $0.saleAmount }.reduce(0,+)
//Or as suggested by Mr Martin: let sum = element.value.reduce(0, { $0 + $1.saleAmount })
return Sale(soldBy: element.key, saleAmount: sum)
}
现在您可以打印结果了:
for s in groupedSales {
print(s.soldBy, s.saleAmount)
}
//ABC 5699.67
//DEF 1111.44
为方便起见,我已将此初始化程序添加到Sale
类中:
class Sale {
var soldBy : String = ""
var saleAmount : Double = 0.00
init(soldBy: String, saleAmount: Double) {
self.soldBy = soldBy
self.saleAmount = saleAmount
}
}
答案 4 :(得分:0)
从@DaniyalRaza的答案开始,并进行一些清理:
readAsArrayBuffer