Reputation:
I have a certain string given like so..
let string = "[@he man:user:123] [@super man:user:456] [@bat man:user:789]"
Now, I need an array containing just the name and the id. For that, I applied the following regex..
extension String {
func findMentionText2() -> [[String]] {
let regex = try? NSRegularExpression(pattern: "(@\\w+(?: \\w+)*):user:(\\w+)", options: [])
if let matches = regex?.matches(in: self, options:[], range:NSMakeRange(0, self.count)) {
return matches.map { match in
return (1..<match.numberOfRanges).map {
let rangeBounds = match.range(at: $0)
guard let range = Range(rangeBounds, in: self) else {
return ""
}
return String(self[range])
}
}
} else {
return []
}
}
}
Now when I do let hashString = string.findMentionText()
and print hashString
, I get an array like so..
[["@he man", "123"], ["@super man", "456"], ["@bat man", "789"]]
So far so good..:)
Now I made a typealias and want to add it to an array.. So I did this...
typealias UserTag = (name: String, id: String)
var userTagList = [UserTag]()
and then,
let hashString2 = string.findMentionText2()
for unit in hashString2 {
let user: UserTag = (name: unit.first!, id: unit.last!)
userTagList.append(user)
}
for value in userTagList {
print(value.id)
print(value.name)
}
Now here, instead of giving unit.first
and unit.last
in let user: UserTag = (name: unit.first!, id: unit.last!)
, want to add the name
and id
to the typealias as and when they are matched from the regex..ie.when I get the name or id, it should be added to the array instead of giving unit.first
or unit.last
..
How can I achieve that..?
Upvotes: 0
Views: 62
Reputation: 318804
You just need to refactor your map
to generate an array of UserTag
instead of an array of string arrays. Here's one approach:
typealias UserTag = (name: String, id: String)
extension String {
func findMentionText2() -> [UserTag] {
let regex = try? NSRegularExpression(pattern: "(@\\w+(?: \\w+)*):user:(\\w+)", options: [])
if let matches = regex?.matches(in: self, options:[], range:NSMakeRange(0, self.count)) {
return matches.compactMap { match in
if match.numberOfRanges == 3 {
let name = String(self[Range(match.range(at: 1), in:self)!])
let id = String(self[Range(match.range(at: 2), in:self)!])
return UserTag(name: name, id: id)
} else {
return nil
}
}
} else {
return []
}
}
}
let string = "[@he man:user:123] [@super man:user:456] [@bat man:user:789]"
print(string.findMentionText2())
But I suggest you create a struct
instead of using a tuple. It doesn't really change the implementation of findMentionText2
but using a struct lets you add other properties and methods as needed.
Upvotes: 1