在自定义对象数组中查找项和更改值-Swift

我有课

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


}
}

我就这么用

var array: [InboxInterests] = [InboxInterests]()

添加项目

let post = InboxInterests(title: "test",eventID : 1, count: "test", added: 0)
self.array.append(post)

我想通过 eventID键找到索引,并在同一索引中更改 added键的值

这怎么可能?

102820 次浏览

因为您使用的是 同学们,所以使用 filter 并首先查找值:

array.filter({$0.eventID == id}).first?.added = value

在这里你:

  1. 将数组过滤到与事件 ID 匹配的元素
  2. 选择第一个结果,如果有的话
  3. 然后设置值

这是因为类是通过引用传递的。编辑来自 array.filter({$0.eventID == id}).first?的返回值时,将编辑基础值。如果您使用的是 结构,您需要查看下面的答案

编辑: 在 Swift 3中,你可以为自己节省几个字符

array.first({$0.eventID == id})?.added = value

编辑: Swift 4.2:

array.first(where: { $0.eventID == id })?.added = value
array.filter {$0.eventID == id}.first?.added = value

对我来说,上面的答案不起作用。所以,我要做的是首先找到我要替换的对象的索引然后使用索引用新值替换它

if let row = self.upcoming.index(where: {$0.eventID == id}) {
array[row] = newValue
}

Swift 5.0:

if let row = self.upcoming.firstIndex(where: {$0.eventID == id}) {
array[row] = newValue
}

在这种情况下,过滤操作符不是最好的,因为类是通过引用传递的,所以它对某些人有效。

说明: (你可以在操场上复制以下代码,如果你想验证它)。

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

数组是通过值而不是引用来复制的,所以当你使用过滤器的时候你是在创建一个新的数组(不同于初始数组) ,但是当你修改新的数组的时候,初始数组也会被修改,因为它们都指向同一个类(类是通过引用传递的) ,所以在过滤器之后你的数组会被修改,新的数组会被释放。因此,在这种情况下,它将打印“ “违约”、“违约”,然后 “默认”“修改”

如果你为 struct改变 class会发生什么,值将通过值而不是引用传递,所以你将有2个数组在内存中有不同的值,所以如果你再次通过 arrayBooks,它将打印之前的过滤器 “违约”,“违约”,然后 “违约”,“违约”再次。因为当您使用过滤器时,您正在创建和修改一个新数组,如果您不存储它,它将被释放)。

解决方案是使用 map,创建一个新数组,其中包含所有值,但是包含我们需要的修改过的项或字段,然后用新数组替换数组。这将打印 “违约”,“违约”之前的地图,然后 “默认”,“修改”

这将适用于结构、类和您想要的一切:)。

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

如果你让你的类符合 Equatable,那么这个方法就可以奏效:

extension Array where Element: Equatable {
@discardableResult
public mutating func replace(_ element: Element, with new: Element) -> Bool {
if let f = self.firstIndex(where: { $0 == element}) {
self[f] = new
return true
}
return false
}
}

使用方法如下:

array.replace(prev, with: new)
array = array.map { $0.eventID == id ? newValue : $0 }