Reputation: 175
I have a class that contains a name, an image, a dashed form of the name, and the length of the name. For example, I could have "dog", an image of a dog, "---", and name length 3.
I just want to set name and pic for each object and have dashName
and nameLength
set automatically.
class Answer {
var name = "name"
var image: UIImage?
var dashName = "name"
var nameLength = 0
init(){
var a = 0
nameLength = name.characters.count
while a <= nameLength {
if (name[a] == " ") {dashName[a] = " "}
else {dashName[a] = "-"}
a += 1
}
}
}
The problem is the error that says: "cannot assign through subscript: subscript is get-only" and another error that says: "subscript is unavailable: cannot subscript String with an Int"
Upvotes: 4
Views: 4031
Reputation: 16347
Because String
's subscript operator is get-only, use map
method instead, like:
class Answer {
var name = "name"
var image: UIImage?
var dashName = "name"
var nameLength = 0
init(){
dashName = String(name.map {$0 == " " ? " " : "-"})
}
}
Upvotes: 2
Reputation: 8826
As mentioned before,
Swift's String
class is what other languages call a StringBuilder
class, and for performance reasons, Swift does NOT provide setting character by index; If you don't care about performance a simple solution could be:
public static func replace(_ string: String, at index: Int, with value: String) {
let start = string.index(string.startIndex, offsetBy: index)
let end = string.index(start, offsetBy: 1)
string.replaceSubrange(start..<end, with: value)
}
Or as an extension:
extension String {
public func charAt(_ index: Int) -> Character {
return self[self.index(self.startIndex, offsetBy: index)];
}
public mutating func setCharAt(_ index: Int, _ new: Character) {
self.setCharAt(index, String(new))
}
public mutating func setCharAt(_ index: Int, _ new: String) {
let i = self.index(self.startIndex, offsetBy: index)
self.replaceSubrange(i...i, with: new)
}
}
Note how above needs to call
index(...)
method to convert integer to actual-index!? It seems, Swift implementsString
like a linked-list, whereappend(...)
is really fast, but even finding the index (without doing anything with it) is a linear-time operation (and gets slower based on concatenation count).
Upvotes: 1
Reputation: 1509
The subscript operator for String
is get-only, which means you can only read from a string using it, and have to use something else to write to a mutable String.
You can solve this issue, and clean up the code by using a map
function on name
Swift 4
class Answer {
var name = "name"
var image: UIImage?
var dashName = "name"
var nameLength = 0
init()
{
nameLength = name.count
dashName = name.map { $0 == " " ? " " : "-" }.joined()
}
}
Swift 3
class Answer {
var name = "name"
var image: UIImage?
var dashName = "name"
var nameLength = 0
init()
{
nameLength = name.characters.count
dashName = name.characters.map { $0 == " " ? String(" ") : String("-") }.joined()
}
}
Upvotes: 0