计算集合中项目的出现次数

时间:2017-06-13 18:23:47

标签: ios swift

我正在寻找一种方法来计算将产品添加到订单的次数(我是Swift的新手)< / p>

struct Product {
  var name: String
  var price: Double
}

struct Order {
  var productsSold: [Product] = []
}

currentOrder = Order()
currentOrder.productsSold.append(products[1]) //From a JSON object "products"
currentOrder.productsSold.append(products[1])
currentOrder.productsSold.append(products[2])
currentOrder.productsSold.append(products[4])

我想要遵循结果,但我无法找到方法:

currentOrder.list() --> product_1 x2 // product_2 x1 // product_4 x1

我只能列出所有产品:

//Inside struc Order
func listProductsSold() {
  if productsSold.count>0 {
    for product in productsSold {
      product.printProduct()
    }
  }
}
//Inside struc Product
func printProduct() {
    print("Nom: \(name), price: \(price), couleur: \(color)")
}

然后:

currentOrder.listProductsSold()

//Which give:
//Nom: Menu cheese, price: 17.0, couleur: rgb(247, 171, 56)
//Nom: Menu cheese, price: 17.0, couleur: rgb(247, 171, 56)
//Nom: Rouge n1, price: 18.0, couleur: rgb(166, 77, 121)
//Nom: Vin vigneron, price: 22.0, couleur: rgb(166, 77, 121)

2 个答案:

答案 0 :(得分:1)

首先需要“分组依据”功能将所有相同的产品收集到一个数组中。可以在this answer

中找到此类函数的示例
index returns 5
42

然后你可以这样做:

public extension Sequence {
    func group<U: Hashable>(by key: (Iterator.Element) -> U) -> [U:[Iterator.Element]] {
        var categories: [U: [Iterator.Element]] = [:]
        for element in self {
            let key = key(element)
            if case nil = categories[key]?.append(element) {
                categories[key] = [element]
            }
        }
        return categories
    }
}

它的作用:

  • let orderSummary = currentOrder.productsSold .group { $0.name } .sorted { $0.key < $1.key } .map { "\($0.key) x \($0.value.count)" } .joined(separator: ", ") .group分组到字典中,其关键字是产品名称,值是一组具有相同名称的产品。
  • productSolds按键(即产品名称)对键值对的集合进行排序
  • .sorted.map
  • 模板中为每个产品构建摘要字符串
  • product_name x count将这些字符串连接成一个整体订单摘要。

答案 1 :(得分:0)

作为计算每个订单销售产品数量的简单解决方案,使用带有产品名称和计数的字典:

        var productsCount = [String: Int]()

        for product in currentOrder.productsSold {
            if let countedProduct = productsCount[product.name] {
                productsCount[product.name] =  productsCount[product.name]! + 1
            } else {
                productsCount[product.name] = 1
            }
        }

修改

修改了使用Product而不是String作为字典键的示例。

首先更改Product以实施HashableEquatable协议:

struct Product: Hashable {
    var name: String
    var price: Double

    var hashValue: Int {
        get {
            return self.name.hashValue
        }
    }

    static func ==(lhs: Product, rhs: Product) -> Bool {
        return lhs.name == rhs.name
    }
}

然后将密钥字典中的类型更改为Product

var productsCount = [Product: Int]()

for product in currentOrder.productsSold {
    if let countedProduct = productsCount[product] {
        productsCount[product] =  productsCount[product]! + 1
    } else {
        productsCount[product] = 1
    }
}