Reputation: 3618
I've been playing about with functional programming in Swift. However, I've encountered a problem.
If I call map on a collection of one type, how do I create a new collection of another type?
var fontFamilyMembers = [[Any]]()
//...
let postscriptNames = fontFamilyMembers.map {
[
"name": $0[0] as! String,
"weight": $0[2] as! Int,
"traits": $0[3] as! UInt
]
}
// Error: Value of type 'Any?' has no member 'count'
lengths = postscriptNames.map { $0["name"].count }
I understand I need to cast $0["name"]
as a string. Why do I have to do that when I have already done it above? ("name": $0[0] as! String
). Is that because postscriptNames
is also type [[Any]]()
?
I've tried this:
// Error: Cannot convert value of type 'Int' to closure result type 'String'
fontPostscriptNames = postscriptNames.map { ($0["name"] as! String).count }.joined(separator: "\n")
…but know I'm doubly confused.
How do I get map to return the count of each "name"
?
My original question still stands. However, I can avoid the problem altogether by using a struct as opposed to a dictionary which I assume is preferred in Swift.
let postscriptNames = fontFamilyMembers.map {
(
name: $0[0] as! String,
weight: $0[2] as! Int,
traits: $0[3] as! UInt
)
}
lengths = postscriptNames.map { $0.name.count }
Upvotes: 0
Views: 703
Reputation: 464
Is that because postscriptNames is also type [Any]?
Yes. And as postscriptNames
is of type [Any]
, you need to downcast $0.name
to String
lengths = postscriptNames.compactMap { ($0.name as? String).count }
Downcast it to String to get the count.
Upvotes: 2