4

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"

3 Answers 3

2

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 == " " ? " " : "-"})
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Spaces should be left alone, any other character should be replaced by a "-"
1

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 implements String like a linked-list, where append(...) 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).

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.