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方法来改进这个类。我在回答中提到了修改。我已经明白了,我的意思是你应该通过更好地描述你所做的来改进你的答案。