【问题标题】:Set (Collection) - Insert multiple elementsSet (Collection) - 插入多个元素
【发布时间】:2018-07-26 14:51:25
【问题描述】:

Set 是唯一元素的无序集合。和数组差不多。

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

insert(_:)

@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)'的函数中缺少返回

有什么办法可以解决这个问题。有没有更好的解决方案/方法来处理这个操作?

【问题讨论】:

  • 为什么要返回元组?
  • 这是单个 Set 元素的方法 insert(_:) 的默认/实际定义。我想创建一个相同的函数,但它应该接受多个 Set 元素。
  • 但是您希望行为是什么?在什么情况下它会返回inserted: true?何时插入一个值?没有表现不同的“相同功能”。由您决定函数返回什么。何时插入所有值? formUnion 没有提供您的用例需要什么?在任何情况下,正如米兰所说,如果你想退回它,你需要真正退回它。

标签: ios swift set tuples swift-extensions


【解决方案1】:

问题下的 cmets 中已指出,但我想明确指出,有一种方法可以达到同样的目的:

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"]"

来源:Apple Developer


还有一个不可变的变体,它返回一个包含联合的新实例:

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"]"

来源:Apple Developer

【讨论】:

    【解决方案2】:

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

    union - 不可变函数
    unionInPlace(高达 Swift 3)=> formUnion - 可变函数

    [Mutable vs Immutable]

    阅读更多here

    【讨论】:

    • 非常感谢! formUnion 函数是我的选择)
    【解决方案3】:

    您的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 实现,您可以有两个不同的将被评估为相同的对象。在这种情况下,第二个论点可能对我们很重要。

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

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

    【讨论】:

    • 很好.. 谢谢你的回答,但我做到了。我想让它与单个 Set 元素的方法 insert(_:) 的实际定义非常相似。我想创建一个相同的函数,但它应该接受多个 Set 元素。
    【解决方案4】:

    我认为您正在寻找的是:

    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)
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-12-31
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多