我创建以下对象:
class Order {
var productId : Int
var userId : Int
var qty : Int
init(productId: Int, userId: Int, qty: Int) {
self.productId = productId
self.userId = userId
self.qty = qty
}
}
然后我创建了以下数组:
var arrayOfOrders = [Order(productId: 1, userId: 1, qty: 5),
Order(productId: 1, userId: 2, qty: 10),
Order(productId: 1, userId: 2, qty: 15),
Order(productId: 2, userId: 1, qty: 20),
Order(productId: 2, userId: 1, qty: 10),
Order(productId: 2, userId: 2, qty: 5),
Order(productId: 3, userId: 1, qty: 15),
Order(productId: 3, userId: 1, qty: 5)]
我需要获得productID和userID的唯一组合,并在新的[Order]数组中总结数量,如下所示:
是否可以使用诸如reduce或map这样的高阶函数?任何其他简单方法都将非常有帮助。 预先感谢您的帮助
答案 0 :(得分:2)
base
[a,c]
[c,e]
[a,h]
请注意与使用SQL GROUP BY /聚合函数的相似之处,
struct Key: Hashable
{
var userId: Int
var productId: Int
}
// 1. Group by Key (userId, productId)
let grouped = Dictionary(grouping: arrayOfOrders) { o in
Key(userId: o.userId, productId: o.productId)
}
// 2. Add up each group's quantity
let summed = grouped.map { group -> Order in
let qty = group.value.reduce(0) { (qty,order) in
qty + order.qty
}
return Order(productId: group.key.productId,
userId: group.key.userId,
qty: qty)
}
答案 1 :(得分:0)
这是一种有趣的方式(也许有点愚蠢)。首先,将您的类更改为不依赖于pacman -S
的Hashable结构(这是Swift 4.2或更高版本),如下所示:
awk '{print "pacman -S " $0;}' tmp.txt > file1.txt
现在将订单放入集合中,从而对它们进行唯一化,同时将qty
更改为struct Order : Hashable {
static func ==(lhs:Order,rhs:Order) -> Bool {
return lhs.productId == rhs.productId && lhs.userId == rhs.userId
}
func hash(into hasher: inout Hasher) {
productId.hash(into:&hasher)
userId.hash(into:&hasher)
}
// ... and the rest is as before
}
:
qty
现在,这是一次快速的单遍操作,可以将0
值总计到集合中:
var set = Set(arrayOfOrders.map { order -> Order in
var order = order
order.qty = 0
return order
})
结果(qty
):
arrayOfOrders.forEach { order in
if var totalOrder = set.remove(order) {
totalOrder.qty += order.qty
set.insert(totalOrder)
}
}