Set(Collection) - 插入多个元素

Kru*_*nal 14 tuples set ios swift swift-extensions

Set是一系列独特元素的无序集合.几乎与数组类似.

我想在一个Set中添加/插入多个元素String.但是只提供了一种方法,只能插入一个元素(接受单个Set元素作为参数参数),我收集了字符串(id).

插入(_:)

@discardableResult mutating func insert(_ newMember: Set.Element) -> (inserted: Bool, memberAfterInsert: Set.Element)
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

我尝试过:
我尝试创建一个非常类似于insert(_:)方法的扩展,但它可以接受多个Set元素.它与使用迭代而不是集合相同,但不需要在任何地方手动处理它.

extension Set {

    @discardableResult mutating func insert(_ newMembers: [Set.Element]) -> (inserted: Bool, memberAfterInsert: Set.Element) {

        newMembers.forEach { (member) in
            self.insert(member)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它应该工作,如果我按预期返回一个元组但不知道如何以及在哪里(哪一行)以及返回值的内容.

这是错误消息.

期望返回的函数中缺少返回'(inserted:Bool,memberAfterInsert:Set.Element)'

在此输入图像描述

什么可以解决这个问题.是否有更好的解决方案/方法来处理此操作?

Ark*_*dii 26

在问题的评论中指出了这一点,但我想清楚地说明有一种方法可以达到同样的目的:

mutating func formUnion<S>(_ other: S) where Element == S.Element, S : Sequence
Run Code Online (Sandbox Code Playgroud)

用法:

var attendees: Set = ["Alicia", "Bethany", "Diana"]
let visitors = ["Diana", "Marcia", "Nathaniel"]
attendees.formUnion(visitors)
print(attendees)
// Prints "["Diana", "Nathaniel", "Bethany", "Alicia", "Marcia"]"
Run Code Online (Sandbox Code Playgroud)

资料来源:Apple Developer


还有一个不可变的变量,它返回一个包含union的新实例:

func union<S>(_ other: S) -> Set<Set.Element> where Element == S.Element, S : Sequence
Run Code Online (Sandbox Code Playgroud)

用法:

let attendees: Set = ["Alicia", "Bethany", "Diana"]
let visitors = ["Marcia", "Nathaniel"]
let attendeesAndVisitors = attendees.union(visitors)
print(attendeesAndVisitors)
// Prints "["Diana", "Nathaniel", "Bethany", "Alicia", "Marcia"]"
Run Code Online (Sandbox Code Playgroud)

资料来源:Apple Developer


yoA*_*ex5 12

a.union(b) - a ? b- 结果集包含来自a和的所有元素b

union-不可变函数
unionInPlace(最多 Swift 3)=> formUnion- 可变函数

[可变 vs 不可变]

在这里阅读更多

  • 多谢!formUnion 函数是我的选择) (2认同)

Mil*_*sáľ 6

您的insert声明声明该方法返回一个元组:(inserted: Bool, memberAfterInsert: Set.Element)但您的方法不返回任何内容.

只需使用:

@discardableResult mutating func insert(_ newMembers: [Set.Element]) {

    newMembers.forEach { (member) in
        self.insert(member)
    }
}
Run Code Online (Sandbox Code Playgroud)

UPDATE

最接近得到的是我相信:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

推理:

文档到插入说:

回报价值

(true, newMember)如果newMember没有包含在集合中.如果一个元素newMember已经包含在集合中,则该方法返回(false, oldMember),其中oldMember是等于的元素newMember.在某些情况下,oldMember可以newMember通过身份比较或其他方式区分.

例如,对于set,{1, 2, 3}如果你尝试插入2,元组将返回(false, 2),因为2已经存在.元组的第二项是来自集合的对象,而不是你提供的对象 - 这里有Int它是无法区分的,因为只有数字2等于2,但根据Equatable实现,你可以有两个不同的对象,它们将被评估为相同.在这种情况下,第二个论点可能对我们很重要.

不管怎么说,我想说的是,一个单一的元组因此对应于一个单一的 newMember,你尝试插入.如果您尝试插入多个新成员,则无法仅通过使用单个元组来描述该插入 - 其中一些新成员可能已经存在,因此对于第一个参数false,可能会成功插入其他一些成员,因此对他们来说,元组的第一个论点是true.

因此,我认为正确的方法是返回一个元组数组[(inserted: Bool, memberAfterInsert: Set.Element)].