如@rmaddy已经评论过的那样,您可以按照以下方式使用FoundationNSCountedSet:
import Foundation
let values = [65.0, 65.0, 65.0, 55.5, 55.5, 30.25, 30.25, 27.5]
let countedSet = NSCountedSet(array: values)
print(countedSet.count(for: 65.0))
for value in countedSet {
print("Element:", value, "count:", countedSet.count(for: value))
}
Xcode 11 • Swift 5.1
你也可以扩展NSCountedSet来返回一组元组或一个字典:
extension NSCountedSet {
var occurences: [(object: Any, count: Int)] { map { ($0, count(for: $0))} }
var dictionary: [AnyHashable: Int] {
reduce(into: [:]) {
guard let key = $1 as? AnyHashable else { return }
$0[key] = count(for: key)
}
}
}
let values = [65.0, 65.0, 65.0, 55.5, 55.5, 30.25, 30.25, 27.5]
let countedSet = NSCountedSet(array: values)
for (key, value) in countedSet.dictionary {
print("Element:", key, "count:", value)
}
对于一个纯Swift的解决方案,我们可以扩展Sequence
并将其元素限制为Hashable
:
extension Sequence where Element: Hashable {
var frequency: [Element: Int] { reduce(into: [:]) { $0[$1, default: 0] += 1 } }
}
let values = [65.0, 65.0, 65.0, 55.5, 55.5, 30.25, 30.25, 27.5]
let frequency = values.frequency
frequency[65]
for (key, value) in frequency {
print("Element:", key, "count:", value)
}
这些将被打印
Element: 27.5 count: 1
Element: 30.25 count: 2
Element: 55.5 count: 2
Element: 65 count: 3
如果您有一个自定义结构的集合,我们可以创建一个通用的方法,并使用关键路径语法如下:
如果您拥有自定义结构的集合,我们可以创建一个通用方法并使用关键路径语法,如下所示:
extension Sequence {
func sum<T: Hashable>(of property: (Element) -> T) -> [T: Int] {
reduce(into: [:]) { $0[property($1), default: 0] += 1 }
}
func sum<T: Hashable, A: AdditiveArithmetic>(of property: (Element) -> T, by adding: (Element) -> A) -> [T: A] {
reduce(into: [:]) { $0[property($1), default: .zero] += adding($1) }
}
}
使用方法:
struct Product {
let id: String
let name: String
let quantity: Int
let price: Decimal
let total: Decimal
}
let products = [
("1", "iPhone", 2, Decimal(string: "499.99")!, Decimal(string: "999.98")!),
("2", "MacBook Pro", 1, Decimal(string: "2499.99")!, Decimal(string: "2499.99")!),
("3", "iPhone", 3, Decimal(string: "1199.99")!, Decimal(string: "3599.97")!),
("4", "iPhone", 1, Decimal(string: "999.99")!, Decimal(string: "999.99")!),
("5", "MacBook Pro", 2, Decimal(string: "1499.99")!, Decimal(string: "2999.98")!)
].map(Product.init)
let sum1 = products.sum(of: \.name)
sum1["iPhone"]
sum1["MacBook Pro"]
let sum2 = products.sum(of: \.name, by: \.quantity)
sum2["iPhone"]
sum2["MacBook Pro"]
let sum3 = products.sum(of: \.name, by: \.total)
sum3["iPhone"]
sum3["MacBook Pro"]
NSCountedSet
类。 - rmaddy