Set est une collection non ordonnée d'éléments uniques. Presque similaire au tableau.
Je veux ajouter/insérer plusieurs éléments dans un Set
de String
. Mais il n'y a qu'une seule méthode fournie qui ne peut insérer qu'un seul élément (accepte un seul élément Set comme argument de paramètre) et j'ai une collection de chaîne (id).
@discardableResult mutating func insert(_ newMember: Set.Element) -> (inserted: Bool, memberAfterInsert: Set.Element)
Comment puis je faire ça?
Ce que j'ai essayé:
J'ai essayé de créer une extension très similaire à la méthode insert(_:)
mais elle peut accepter plusieurs éléments Set. Ce serait la même chose que l'utilisation de l'itération sur la collection, mais vous n'avez pas besoin de la gérer manuellement partout.
extension Set {
@discardableResult mutating func insert(_ newMembers: [Set.Element]) -> (inserted: Bool, memberAfterInsert: Set.Element) {
newMembers.forEach { (member) in
self.insert(member)
}
}
}
Cela devrait fonctionner, si je retourne un tuple comme prévu, mais je ne sais pas comment et où (quelle ligne) et quoi renvoyer une valeur.
Voici un message d'erreur.
Retour manquant dans une fonction censée retourner '(inséré: Bool, memberAfterInsert: Set.Element)'
Quelle peut être la solution à cela. Existe-t-il une meilleure solution/approche pour gérer cette opération?
Votre déclaration insert
indique que la méthode retourne un Tuple: (inserted: Bool, memberAfterInsert: Set.Element)
, Mais votre méthode ne retourne rien.
Utilisez simplement:
@discardableResult mutating func insert(_ newMembers: [Set.Element]) {
newMembers.forEach { (member) in
self.insert(member)
}
}
[~ # ~] mise à jour [~ # ~]
Le plus proche à obtenir est celui-ci je crois:
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
}
}
Raisonnement:
Les docs à l'encart disent:
Valeur de retour
(true, newMember)
SinewMember
n'était pas contenu dans l'ensemble. Si un élément égal ànewMember
était déjà contenu dans l'ensemble, la méthode renvoie(false, oldMember)
, OùoldMember
est l'élément qui était égal ànewMember
. Dans certains cas,oldMember
peut être distingué denewMember
par comparaison d'identité ou par d'autres moyens.
Par exemple, pour l'ensemble {1, 2, 3}
Si vous essayez d'insérer 2
, Le tuple renverra (false, 2)
, Car 2
Était déjà là. Le deuxième élément du tuple serait un objet de l'ensemble et non celui que vous avez fourni - ici avec Ints, il est impossible de le distinguer, car seul le nombre 2
Est égal à 2
, Mais en fonction de Equatable
mise en œuvre, vous pouvez avoir deux objets différents qui seraient évalués comme étant identiques. Dans ce cas, le deuxième argument pourrait être important pour nous.
Quoi qu'il en soit, ce que j'essaie de dire, c'est qu'un seul Tuple correspond donc à un singlenewMember
que vous essayez d'insérer. Si vous essayez d'insérer plusieurs nouveaux membres, vous ne pouvez pas décrire cette insertion simplement en utilisant un seul tuple - certains de ces nouveaux membres peuvent déjà avoir été là, donc pour le premier argument serait false
, certains autres membres pourrait être inséré avec succès, donc pour eux le premier argument de Tuple serait true
.
Par conséquent, je crois que la bonne façon est de renvoyer un tableau de tuples [(inserted: Bool, memberAfterInsert: Set.Element)]
.
Cela a été souligné dans les commentaires sous la question, mais je voudrais indiquer clairement qu'il existe une méthode dans le même but:
mutating func formUnion<S>(_ other: S) where Element == S.Element, S : Sequence
Usage:
var attendees: Set = ["Alicia", "Bethany", "Diana"]
let visitors = ["Diana", "Marcia", "Nathaniel"]
attendees.formUnion(visitors)
print(attendees)
// Prints "["Diana", "Nathaniel", "Bethany", "Alicia", "Marcia"]"
Source: développeur Apple
Il existe également une variante immuable qui renvoie une nouvelle instance contenant l'union:
func union<S>(_ other: S) -> Set<Set.Element> where Element == S.Element, S : Sequence
Usage:
let attendees: Set = ["Alicia", "Bethany", "Diana"]
let visitors = ["Marcia", "Nathaniel"]
let attendeesAndVisitors = attendees.union(visitors)
print(attendeesAndVisitors)
// Prints "["Diana", "Nathaniel", "Bethany", "Alicia", "Marcia"]"
Source: développeur Apple
Opérations des ensembles fondamentaux
union
fonction immuable, retourne un nouvel ensemble avec les éléments de ceci et de l'ensemble donné.
func union(_ other: Self) -> Self
formUnion
(unionInPlace
jusqu'à Swift version 3) fonction mutable, ajoute les éléments de l'ensemble donné à l'ensemble.
mutating func formUnion(_ other: Self)