Whats the proper way to implement this ? preferably in one line.
var name: String?
...
let username = "#" + name
Note: username must be String? I don't want to unwrap name for concatenation.
Edit: if name is nil, username should also be nil.
You can use the map method of Optional:
let username = name.map { "#" + $0 }
If name is nil then the closure is not executed and the result is nil. Otherwise the closure is evaluated with $0 set to the unwrapped name.
Try this:
let username = name.flatMap { "#\($0)" }
EDITED based on updated requirements:
You can do it a couple of ways. Here's one:
var name: String?
var username: String?
if let name = name {
username = "#" + name
}
Probably the simplest and more readable option is using if let but you could also define a method to prepend a String, opposed to String.append and then use optional chaining:
extension String {
func prepending(prefix: String) -> String {
return prefix + self
}
}
var name: String?
let username = name?.prepending("#")
Related
I have below func in my class.
static func getFirstCharInName(strName: String) -> String {
let firstCharInName = String(strName.first)
return firstCharInName.trim()
}
I encountered this err:
Value of optional type 'Character?' must be unwrapped to a value of type 'Character'
What seems to be the problem?
Thanks
func getFirstCharInName(strName: String) -> String {
let indexStartOfText = strName.index(strName.startIndex, offsetBy: 0)
let indexEndOfText = strName.index(strName.startIndex, offsetBy: 0)
let firstChar = String(strName[indexStartOfText...indexEndOfText])
return firstChar
}
This error means that the expression has optional value (the value can be nil) that is not yet unwrapped, strName.first returns an optional value of Character?, but your function demands a returning type of String which is not an optional type.
So, in order to fix this, you need to unwrap the optional value strName.first, it seems like you are not familiar with optionals, here's the code for your case (choose one from two options):
func getFirstCharInName(strName: String) -> String {
// option 1: force unwrap - can cause fatal error
return String(strName.first!)
// option 2: optional binding
if let firstCharInName = strName.first {
return String(firstCharInName)
} else {
// if the optional value is nil, return an empty string
return ""
}
}
PS. I don't really understand the function trim() in your question, but if you mean to strip away the blank spaces like " ", you can do:
firstCharInName.trimmingCharacters(in: .whitespaces)
Avoid the optional simply with prefix, it's totally safe. if there is no first character you'll get an empty string.
static func getFirstChar(in name: String) -> String { // the function name getFirstChar(in name is swiftier
return String(name.prefix(1))
}
I don't know what the trim function is supposed to do.
It means that value of optional type 'Character?' (as result of your part of code strName.first) must be unwrapped to a value of type 'Character' before you will be gonna cast it to String type.
You may use this variant:
func getFirstCharInName(strName: String) -> String {
return strName.count != 0 ? String(strName.first!) : ""
}
As you can see, the exclamation point is in the string strName.first! retrieves the optional variable as it was needed.
you can do something like that:
extension String {
var firstLetter: String {
guard !self.isEmpty else { return "" }
return String(self[self.startIndex...self.startIndex])
}
}
then
let name = "MilkBottle"
let first = name.firstLetter // "M"
I have code like this that I frequently use:
var myName = "Guest"
if let data = dictionary["name"] as? String { myName = data; }
func supply (name: myName)
How to make it like this (or similar):
guard let myName = dictionary["name"] as? String else { let myName = "Guest" }
func supply (name: myName)
I prefer the latter because it involves less variable names and also more straightforward. I have tried the code, but it looks like the let myName = "Guest" inside the brackets is limited by the variable scope inside the brackets only. How to make it possible? Thanks.
Use a nil-coalescing operator.
let myName = (dictionary["name"] as? String) ?? "Guest"
This will try to unwrap the value for key "name" as string and fall back to "Guest" in the event there is no value for key "name" or if the value cannot be cast as String
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html
I want to check whether my filename with just prefix is exist or not in Swift.
E.g
My file name is like Companies_12344
So after _ values are dynamic but "Companies_" is static.
How can i do that?
My code below For split
func splitFilename(str: String) -> (name: String, ext: String)? {
if let rDotIdx = find(reverse(str), "_")
{
let dotIdx = advance(str.endIndex, -rDotIdx)
let fname = str[str.startIndex..<advance(dotIdx, -1)]
println("splitFilename >> Split File Name >>\(fname)")
}
return nil
}
It's not very clear what you want to do, because your code snippet already does check if the string has the prefix.
There's a simpler way, though:
let fileName = "Companies_12344"
if fileName.hasPrefix("Companies") {
println("Yes, this one has 'Companies' as a prefix")
}
Swift's hasPrefix method checks if the string begins with the specified string.
Also, you could split the string easily with this:
let compos = fileName.componentsSeparatedByString("_") // ["Companies", "12344"]
Then you could check if there's a code and grab it with:
if let fileCode = compos.last {
println("There was a code after the prefix: \(fileCode)")
}
I have a problem similar to this question, but the answers there isn't helping me.
I have these lines of code:
var id = item["id"] as? String ?? ""
var name = item["name"] as? String ?? ""
var pic = item["pic"] as? String ?? ""
To me these lines of code a pretty much the same. For Xcode, this is a different matter.
The first line is fine. The second two lines generate this error:
'(key: AnyObject, value: AnyObject)' does not have a member named 'subscript'
Here is some more context for you all:
class func getFromJson(json:NSDictionary) -> [Collection] {
var collections = [Collection]()
if json.count > 0 {
for item in json {
var id = item["id"] as? String ?? ""
var name = item["name"] as? String ?? ""
var pic = item["pic"] as? String ?? ""
var newUser = Collection(id:id, name:name, pic:pic)
collections.append(newUser)
}
}
return collections
}
Can anyone explain to me how to fix this. Bonus points if you can explain why the first line is fine, but the next two nearly identical lines produce errors!
Thanks in advance.
'(key: AnyObject, value: AnyObject)' indicates that item is not an Dictionary but is a Tuple with a single key/value pair.
Iterating dictionaries in swift interates through tuples:
for (key, value) in json {
println(key, value)
}
Your for loop indicates that you are probably wanting a json Array of tuples instead of a json Dictionary.
item["id"] would give you a compile time error if you declared the parameter as a tuple. It seems you stumbled onto something hidden with the language with how either tuples or subscripts work under the hood.
More on Subscripts
More on Types (Tuples)
In “The Swift Programming Language.” book, Apple mentions using if and let together when accessing an optional variable.
The book gives the following code for example:
var optionalString: String? = "Hello"
optionalString == nil
var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
greeting = "Hello, \(name)"
}
What is the advantage of using if let name = optionalName, rather than if optionalName != nil (and always referring to it as, optionalName)? Is there any difference, or is it simply convention?
Because it also unwraps the optional value, so this code:
if let name = optionalName {
greeting = "Hello, \(name)"
}
is equivalent to:
if optionalName != nil {
let name:String = optionalName!
greeting = "Hello, \(name)"
}
This language sugar is known as Optional Binding in Swift.
Optional Types
In Swift T and T? are not the same types, but the underlying value of an optional T? type can easily be realized by using the ! postfix operator, e.g:
let name:String = optionalName!
Which now can be used where a String is expected, e.g:
func greet(name:String) -> String {
return "Hello, \(name)"
}
greet(name)
Although as its safe to do so, Swift does let you implicitly cast to an optional type:
let name = "World"
let optionalName: String? = name
func greet(optionalName:String?) -> String? {
if optionalName != nil {
return "Hello, \(optionalName)"
}
return nil
}
//Can call with either String or String?
greet(optionalName)
greet(name)
It isn't actually needed in that case. You could just use optionalName in the if. But if optionalName was a calculated property it would have to be calculated in the conditional then again in the body. Assigning it to name just makes sure it is only calculated once.