Set是一组无序的独特元素。几乎与数组相似。
我想在Set
String
中添加/插入多个元素。但是只提供了一种方法,只能插入一个元素(接受单个Set元素作为参数参数),我收集了字符串(id)。
@discardableResult mutating func insert(_ newMember: Set.Element) -> (inserted: Bool, memberAfterInsert: Set.Element)
我该怎么做?
我尝试了什么:
我尝试创建一个非常类似于insert(_:)
方法的扩展,但它可以接受多个Set元素。它与使用迭代而不是集合相同,但不需要在任何地方手动处理它。
extension Set {
@discardableResult mutating func insert(_ newMembers: [Set.Element]) -> (inserted: Bool, memberAfterInsert: Set.Element) {
newMembers.forEach { (member) in
self.insert(member)
}
}
}
如果我按预期返回一个元组但不知道如何以及在哪里(哪一行)以及返回值的内容,它应该可以工作。
这是错误消息。
在预期返回的函数中缺少返回'(inserted:Bool,memberAfterInsert:Set.Element)'
可以解决这个问题。是否有更好的解决方案/方法来处理此操作?
答案 0 :(得分:16)
在问题的评论中已经指出,但我想清楚地说明有一种方法可以达到同样的目的:
mutating func formUnion<S>(_ other: S) where Element == S.Element, S : Sequence
用法:
var attendees: Set = ["Alicia", "Bethany", "Diana"]
let visitors = ["Diana", "Marcia", "Nathaniel"]
attendees.formUnion(visitors)
print(attendees)
// Prints "["Diana", "Nathaniel", "Bethany", "Alicia", "Marcia"]"
还有一个不可变的变量,它返回一个包含union的新实例:
func union<S>(_ other: S) -> Set<Set.Element> where Element == S.Element, S : Sequence
用法:
let attendees: Set = ["Alicia", "Bethany", "Diana"]
let visitors = ["Marcia", "Nathaniel"]
let attendeesAndVisitors = attendees.union(visitors)
print(attendeesAndVisitors)
// Prints "["Diana", "Nathaniel", "Bethany", "Alicia", "Marcia"]"
答案 1 :(得分:6)
您的insert
声明声明该方法返回了一个元组:(inserted: Bool, memberAfterInsert: Set.Element)
,但您的方法不会返回任何内容。
只需使用:
@discardableResult mutating func insert(_ newMembers: [Set.Element]) {
newMembers.forEach { (member) in
self.insert(member)
}
}
<强>更新
最接近得到的是我相信:
extension Set {
@discardableResult mutating func insert(_ newMembers: [Set.Element]) -> [(inserted: Bool, memberAfterInsert: Set.Element)] {
var returnArray: [(inserted: Bool, memberAfterInsert: Set.Element)] = []
newMembers.forEach { (member) in
returnArray.append(self.insert(member))
}
return returnArray
}
}
推理:
插页的docs说:
返回值
(true, newMember)
如果集合中未包含newMember
。如果集合中已包含等于newMember
的元素,则该方法返回(false, oldMember)
,其中oldMember
是等于newMember
的元素。在某些情况下,oldMember
可能会通过身份比较或其他方式与newMember
区分开来。
例如,对于设置{1, 2, 3}
,如果您尝试插入2
,则元组将返回(false, 2)
,因为2
已经存在。元组的第二项是来自集合的对象而不是你提供的对象 - 这里有Ints它是无法区分的,因为只有2
的数字等于2
,但取决于Equatable
实现你可以有两个不同的对象,将被评估为相同。在这种情况下,第二个论点可能对我们很重要。
无论如何,我想说的是,单个元组因此对应于您尝试插入的单个 newMember
。如果您尝试插入多个新成员,则无法仅通过使用单个元组来描述该插入 - 其中一些新成员可能已经存在,因此第一个参数将是false
,其他一些成员可能成功插入,因此对于他们来说,元组的第一个参数是true
。
因此,我认为正确的方法是返回一组元组[(inserted: Bool, memberAfterInsert: Set.Element)]
。
答案 2 :(得分:1)
基本设置操作
union
不可变函数,将返回一个新集合,其中包含该集合和给定集合的元素。
func union(_ other: Self) -> Self
formUnion
({{1}之前为Swift版本3)可变函数,将给定集合的元素添加到集合中。
unionInPlace
答案 3 :(得分:1)
我认为您正在寻找的是这个
extension Set {
mutating func insert(_ elements: Element...) {
insert(elements)
}
mutating func insert(_ elements: [Element]) {
for element in elements {
insert(element)
}
}
}
您问题中的示例打破了几个良好的软件编程原则,例如单一职责规则。似乎您的函数正在尝试修改当前集合并返回新集合。那真是令人困惑。您为什么要这么做?
如果您尝试从多个集合中创建一个新集合,则可以执行以下操作:
extension Set {
/// Initializes a set from multiple sets.
/// - Parameter sets: An array of sets.
init(_ sets: Self...) {
self = []
for set in sets {
for element in set {
insert(element)
}
}
}
}