Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Appending text in a loop in Swift

I need to append an array of string and finally get a single string to be displayed in a UILabel in the following format.

Action1 | Action2 | Action3 | Action4

for action in actions {

    actionLabel.text += "\(action.name) |"
}

This gives me the following error.

'String?' is not identical to 'UInt8'.

Any reason for this error? Is there any other way to accomplish this?

Thank you.

like image 692
Isuru Avatar asked Sep 23 '14 06:09

Isuru


2 Answers

This is one of Swift's many cryptic error messages. As far as I can tell because the left side and right side don't match (Optional<String> vs String), its best guess is that you meant for both sides to be UInt8.

To get over the fact that UILabel.text is optional, you can do things the long way:

actionLabel.text = (actionLabel.text ?? "") + "\(action.name) |"

This gets the current value or a blank string and appends the text. You could also avoid the problem functionally:

actionLabel.text = join(" | ", map(actions, { $0.name }))

Update

With regards to iterative solution having an extra | at the end in the "", I was trying to illustrate the solution to just the line causing the error. Your posted code also makes assumptions about actionLabel having been initially blank and has some (likely insignificant) performance costs of setting label text multiple times.

A complete iterative approach could look something like this:

var text = ""
for action in actions {
    if text.isEmpty {
        text = action.name
    } else {
        text += " | \(action.name)"
    }
}
actionLabel.text = text

Mapping and joining are such common operations that most languages have clean succinct ways of doing it without iteration. For example, I would recommend the following in Objective-C:

actionLabel.text = [[actions valueForKeyPath:@"name"] componentsJoinedByString:@" | "];
like image 64
Brian Nickel Avatar answered Nov 10 '22 04:11

Brian Nickel


text property is optional can be nil. You can use optional chaining to over come this. Also set initial text before going through the loop.

if actionLabel.text == nil {
    actionLabel.text = ""
}

for action in actions {
    actionLabel.text? += "\(action.name) |"
}
like image 33
Kirsteins Avatar answered Nov 10 '22 03:11

Kirsteins