Set (Collection) - Вставка нескольких элементов
Набор представляет собой неупорядоченную коллекцию уникальных элементов. Почти похоже на массив.
Я хочу добавить/вставить несколько элементов в 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)
}
}
}
Это должно работать, если я верну кортеж, как и ожидалось, но не знаю, как и где (какая строка) и что вернуть значение.
Вот сообщение об ошибке.
Отсутствует return в функции, ожидаемой для возврата '(вставлено: Bool, memberAfterInsert: Set.Element)'
![enter image description here]()
Что может быть решением этого. Есть ли лучшее решение/подход для обработки этой операции?
Ответы
Ответ 1
В объявлении 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
}
}
Обоснование:
Документы к вкладке говорят:
Возвращаемое значение
(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
Это было указано в комментариях к вопросу, но я хотел бы четко заявить, что для этой же цели существует метод:
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
Ответ 3
Основные операции над множествами
![enter image description here]()
Функция неизменяемого union
возвращает новый набор с элементами как этого, так и данного набора.
func union(_ other: Self) -> Self
formUnion
unionInPlace
formUnion
(unionInPlace
до Swift версии 3) добавляет элементы данного набора в набор.
mutating func formUnion(_ other: Self)