Reputation: 5247
I need to update associated value of Enum
stored in an Array
. How can I access the cell of the proper case without knowing its index?
enum MessageCell {
case from(String)
case to(String)
case subject(String)
case body(String)
}
var cells = [MessageCell.from(""), MessageCell.to(""), MessageCell.subject(""), MessageCell.body("")]
let recipient = "John"
// Hardcoded element position, avoid this
cells[1] = .to(recipient)
// How to find the index of .to case
if let index = cells.index(where: ({ ... }) {
cells[index] = .to(recipient)
}
Upvotes: 4
Views: 4526
Reputation: 80931
As an alternative to using index(where:)
, you could use pattern matching with a for
loop instead in order to iterate over the indices of the elements that match the given case, then simply break
on the first match:
var cells: [MessageCell] = [.from(""), .to(""), .subject(""), .to("")]
let recipient = "John"
for case let (offset, .to) in cells.enumerated() {
cells[offset] = .to(recipient)
break
}
print(cells)
// [MessageCell.from(""), MessageCell.to("John"),
// MessageCell.subject(""), MessageCell.to("")]
Upvotes: 4
Reputation: 154691
Use if case
to test for the enum
case .to
in the closure and return true
if found, otherwise return false
:
if let index = cells.index(where: { if case .to = $0 { return true }; return false }) {
cells[index] = .to(recipient)
}
Here's a complete example:
enum MessageCell {
case from(String)
case to(String)
case subject(String)
case body(String)
}
var cells: [MessageCell] = [.from(""), .to(""), .subject(""), .body("")]
if let index = cells.index(where: { if case .to = $0 { return true }; return false }) {
print(".to found at index \(index)")
}
Output:
.to found at index 1
Upvotes: 14
Reputation: 38833
Here is a simplified demo of how you can solve this so that you get the idea of how this works:
var arr = ["a", "b"] // a, b
if let index = arr.index(where: { $0 == "a" }) {
arr[index] = "c"
}
print(arr) // c, b
In your case:
if let index = cells.index(where: { if case .to = $0 { return true } else { return false } }) {
cells[index] = .to(recipient)
}
Upvotes: 1
Reputation: 24341
Try this:
if let index = cells.index(where: { (messageCell) -> Bool in
switch messageCell
{
case .to(let x):
return x == recipient ? true : false
default:
return false
}
})
{
cells[index] = .to(recipient)
}
Upvotes: 0