Swift如何创建具有多重性的集合(多重集合)
我将两个整数数组相减。我使用集合进行了减法运算:Swift如何创建具有多重性的集合(多重集合),swift,collections,set,multiset,Swift,Collections,Set,Multiset,我将两个整数数组相减。我使用集合进行了减法运算: let numbersA = [1, 2, 3] let numbersB = [3, 4, 5] Set(numbersA).subtracting(numbersB) 但后来我意识到数组中有多重性,我应该考虑它。Swift中多集的数据结构是什么?在Swift 5中,核心库中没有多集实现。 您可以使用字典[元素:多重性]重现多集行为 您的代码将是: let numbersA = [1, 2, 3, 3] let numbersB = [3,
let numbersA = [1, 2, 3]
let numbersB = [3, 4, 5]
Set(numbersA).subtracting(numbersB)
但后来我意识到数组中有多重性,我应该考虑它。Swift中多集的数据结构是什么?在Swift 5中,核心库中没有多集实现。 您可以使用字典
[元素:多重性]
重现多集行为
您的代码将是:
let numbersA = [1, 2, 3, 3]
let numbersB = [3, 4, 5]
Set(numbersA).subtracting(numbersB) // [1, 2, 3]
正如Leo Dabus在评论中指出的那样,这会给你一个无序的收藏
您可以在以下位置找到有关多重集的良好教程: 下面是multiset的一个随时可用的实现。我添加了减法实现。请注意,它可以被视为Multiset的不完整实现,例如,它没有扩展收集协议
//
// Multiset.swift
// Multiset
//
// Created by Simon Whitaker on 28/08/2017.
//
// Extended by Jeremy Cochoy on 17/11/2019
import Foundation
public struct Multiset<T: Hashable> {
private var storage: [T: UInt] = [:]
public private(set) var count: UInt = 0
public init() {}
public init<C: Collection>(_ collection: C) where C.Element == T {
for element in collection {
self.add(element)
}
}
public mutating func add (_ elem: T) {
storage[elem, default: 0] += 1
count += 1
}
public mutating func remove (_ elem: T) {
if let currentCount = storage[elem] {
if currentCount > 1 {
storage[elem] = currentCount - 1
} else {
storage.removeValue(forKey: elem)
}
count -= 1
}
}
public func isSubSet (of superset: Multiset<T>) -> Bool {
for (key, count) in storage {
let supersetcount = superset.storage[key] ?? 0
if count > supersetcount {
return false
}
}
return true
}
public func count(for key: T) -> UInt {
return storage[key] ?? 0
}
public var allItems: [T] {
var result = [T]()
for (key, count) in storage {
for _ in 0 ..< count {
result.append(key)
}
}
return result
}
public func subtracting(_ elems: [T]) -> Multiset<T> {
var resultSet = self
elems.forEach { resultSet.remove($0) }
return resultSet
}
}
// MARK: - Equatable
extension Multiset: Equatable {
public static func == (lhs: Multiset<T>, rhs: Multiset<T>) -> Bool {
if lhs.storage.count != rhs.storage.count {
return false
}
for (lkey, lcount) in lhs.storage {
let rcount = rhs.storage[lkey] ?? 0
if lcount != rcount {
return false
}
}
return true
}
}
// MARK: - ExpressibleByArrayLiteral
extension Multiset: ExpressibleByArrayLiteral {
public init(arrayLiteral elements: T...) {
self.init(elements)
}
}
//
//斯威夫特
//多集
//
//西蒙·惠特克于2017年8月28日创作。
//
//由Jeremy Cochoy于2019年11月17日延长
进口基金会
公共结构多集{
专用变量存储:[T:UInt]=[:]
公私(集合)变量计数:UInt=0
公共init(){}
public init(u集合:C),其中C.Element==T{
对于集合中的元素{
self.add(元素)
}
}
公共变异函数添加(em:T){
存储[elem,默认值:0]+=1
计数+=1
}
公共变异函数删除(em:T){
如果let currentCount=存储器[elem]{
如果currentCount>1{
存储器[elem]=当前计数-1
}否则{
存储移除值(forKey:elem)
}
计数-=1
}
}
公共函数发布集(超集的集合:多集)->Bool{
用于存储中的(键、计数){
让超级集合计数=超级集合存储[键]??0
如果计数>超级设置计数{
返回错误
}
}
返回真值
}
公共函数计数(对于键:T)->UInt{
返回存储器[键]??0
}
公共变量所有项:[T]{
var结果=[T]()
用于存储中的(键、计数){
对于0中的uu..<计数{
result.append(键)
}
}
返回结果
}
公共函数减法(elems:[T])->多集{
var resultSet=self
elems.forEach{resultSet.remove($0)}
返回结果集
}
}
//马克:相等
扩展多集:相等{
公共静态函数==(左:多集,右:多集)->Bool{
如果lhs.storage.count!=rhs.storage.count{
返回错误
}
用于lhs存储中的(lkey,lcount){
设rcount=rhs.存储[lkey]??0
如果lcount!=rcount{
返回错误
}
}
返回真值
}
}
//标记:-ExpressibleByArrayLiteral
扩展多集:ExpressibleByArrayLiteral{
公共init(阵列并行元素:T…){
self.init(元素)
}
}
请解释您在原始解决方案中添加/更改了哪些内容以及原因。现在我发现这个答案不完整,因为我必须将这个答案与链接页面进行直观的比较,以发现有什么变化。请注意,结果将是无序的collection@JoakimDanielson我只添加了一个减法。例如,我们仍然可以通过添加union方法来改进这个类。我在回答中提到了修改。我已经明白了,我的意思是你应该通过更好地描述你所做的来改进你的答案。