J'ai cette classe
class InboxInterests {
var title = ""
var eventID = 0
var count = ""
var added = 0
init(title : String, eventID : NSInteger, count: String, added : NSInteger) {
self.title = title
self.eventID = eventID
self.count = count
self.added = added
}
}
Et je l'utilise comme ça
var array: [InboxInterests] = [InboxInterests]()
Ajouter un item
let post = InboxInterests(title: "test",eventID : 1, count: "test", added: 0)
self.array.append(post)
Je veux trouver l'index par la clé eventID
et changer la valeur de la clé added
dans le même index
Comment est-ce possible?
Utilisez le filtre et commencez par trouver la valeur:
array.filter({$0.eventID == id}).first?.added = value
En cela vous:
EDIT: Dans Swift 3, vous pouvez vous épargner quelques caractères
array.first({$0.eventID == id})?.added = value
EDIT: Swift 4.2:
array.first(where: { $0.eventID == id })?.added = value
array.filter {$0.eventID == id}.first?.added = value
Pour moi, la réponse ci-dessus n'a pas fonctionné. Donc, ce que j'ai fait était d'abord de trouver l'index de l'objet que je veux remplacer, puis en utilisant l'index, le remplacer par la nouvelle valeur
if let row = self.upcoming.index(where: {$0.eventID == id}) {
array[row] = newValue
}
Dans Swift 5.0:
if let row = self.upcoming.firstIndex(where: {$0.eventID == id}) {
array[row] = newValue
}
L'opérateur de filtre n'est pas le meilleur dans ce cas, il fonctionne pour certains d'entre vous car les classes sont passées par référence.
Explication: (vous pouvez copier le code suivant dans un terrain de jeu si vous souhaitez le vérifier).
class Book {
let id: Int
var title = "default"
init (id: Int) {
self.id = id
}
}
var arrayBook = [Book]()
arrayBook.append(Book(id: 0))
arrayBook.append(Book(id:1))
arrayBook.forEach { book in
print(book.title)
}
arrayBook.filter{ $0.id == 1 }.first?.title = "modified"
arrayBook.forEach { book in
print(book.title)
}
Les tableaux sont copiés par valeur et non par référence. Ainsi, lorsque vous utilisez le filtre, vous créez un nouveau tableau (différent du premier), mais lorsque vous modifiez le nouveau, le premier est également modifié car les deux pointent vers la même classe ( classées sont passées par référence), donc après le filtre votre tableau aura changé et le nouveau sera désalloué. Donc, dans ce cas, il affichera "défaut", "par défaut" puis "par défaut," modifié ".
Que se passe-t-il si vous changez class
pour struct
, la valeur sera transmise par valeur non référence afin que vous ayez 2 tableaux en mémoire avec des valeurs différentes, donc si vous passez par arrayBooks
à nouveau, il sera imprimé avant le filtre "default", "default", puis "default", "default" à nouveau. Parce que lorsque vous utilisez le filtre, vous créez et modifiez un nouveau tableau qui sera désalloué si vous ne le stockez pas).
La solution utilise map, créant un nouveau tableau avec toutes les valeurs mais avec les éléments modifiés ou les champs souhaités, puis remplaçons notre tableau par le nouveau. Ceci affichera "défaut", "défaut" avant la carte, puis "défaut", "modifié"
Cela fonctionnera avec les structures, les classes et tout ce que vous voulez :).
struct Book {
let id: Int
var title = "default"
init (id: Int) {
self.id = id
}
}
var arrayBook = [Book]()
arrayBook.append(Book(id: 0))
arrayBook.append(Book(id:1))
arrayBook.forEach { book in
print(book.title)
}
arrayBook = arrayBook.map{
var mutableBook = $0
if $0.id == 1 {
mutableBook.title = "modified"
}
return mutableBook
}
arrayBook.forEach { book in
print(book.title)
}