I have a lot of strings like this one:
"substring1:substring2:...:substring9"
So the number of substrings in string is always 9, and some substrings in string may be empty.
I want to split the string by ":" into array of strings and i do it like this:
let separator = Character(":")
let arrayOfStrings = string.split(separator: separator, maxSplits: 8, omittingEmptySubsequences: false).map({ String($0) })
For example for 13.5k strings it took about 150ms to convert them into arrays of strings.
Is there any other method that is more efficient in terms of time for this task?
Try this:
let arrayOfStrings = string.components(separatedBy: ":")
This should improve performance as it doesn't use .map(), which isn't really required in your case.
Or
As #Martin R suggested, if you can work with an array of SubString instead, the following should perform better:
let arrayOfStrings = string.split(separatedBy: ":")
split returns [Substring] which only uses references, does not allocate a new String and should be faster.
Also, .split is a method on String, (unlike .component which is a method on NSString) and hence there is no bridging conversion as pointed by #JeremyP.
Related
I am trying use String(format:, ) for reading some characters from left or right, do we have something for this job?
for example reading 2 characters from left would be: "AB" like this: "%2L#"
my code:
let stringOfText = String(format: "%#", "ABCDEF")
String(format:) is usually to transform a different value type into a string.
Since you already have a string, you don't really need this method.
try:
https://developer.apple.com/documentation/swift/string/2894830-prefix
It used to be you could use substring to get a portion of a string. That has been deprecated in favor on string index. But I can't seem to make a string index out of integers.
var str = "hellooo"
let newindex = str.index(after: 3)
str = str[newindex...str.endIndex]
No matter what the string is, I want the second 3 characters. So and str would contain "loo". How can I do this?
Drop the first three characters and the get the remaining first three characters
let str = "helloo"
let secondThreeCharacters = String(str.dropFirst(3).prefix(3))
You might add some code to handle the case if there are less than 6 characters in the string
I need to count the number of leading tabs in a Swift string. I know there are fairly simple solutions (e.g. looping over the string until a non-tab character is encountered) but I am looking for a more elegant solution.
I have attempted to use a regex such as ^\\t* along with the .numberOfMatches method but this detects all the tab characters as one match. For example, if the string has three leading tabs then that method just returns 1. Is there a way to write a regex that treats each individual tab character as a single match?
Also open to other ways of approaching this without using a regex.
Here is a non-regex solution
let count = someString.prefix(while: {$0 == "\t"}).count
You may use
\G\t
See the regex demo.
Here,
\G - matches a string start position or end of the previous match position, and
\t - matches a single tab.
Swift test:
let string = "\t\t123"
let regex = try! NSRegularExpression(pattern: "\\G\t", options: [])
let numberOfOccurrences = regex.numberOfMatches(in: string, range: NSRange(string.startIndex..., in: string))
print(numberOfOccurrences) // => 2
I am using Swift 4.2. I am getting extraneous characters when formatting one string (s1) from another string(s0) using the %# format code.
I have searched extensively for details of string formatting but have come up with only partial answers including the code in the second line below. I need to be able to format s1 so that I can customize output from a Swift process. I ask this because I have not found an answer while searching for ways to format a string from a string.
I tried the following three statements:
let s0:[String] = ["abcdef"]
let s1:[String] = [String(format:"%#",s0)]
print(s1)
...
The output is shown below. It may not be clear, here, but there are four leading spaces to the left of the abcdef string.
["(\n abcdef\n)"]
How can I format s1 so it does not include the brackets, the \n escape characters, and the leading spaces?
The issue here is you are using an array but a string in s0.
so the following index will help you.
let s0:[String] = ["abcdef"]
let s1:[String] = [String(format:" %#",s0[0])]
I am getting extraneous characters when formatting one string (s1) from another string (s0) ...
The s0 is not a string. It is an array of strings (i.e. the square brackets of [String] indicate an array and is the same as saying Array<String>). And your s1 is also array, but one that that has one element, whose value is the string representation of the entire s0 array of strings. That’s obviously not what you intended.
How can I format s1 so it does not include the brackets, the \n escape characters, and the leading spaces?
You’re getting those brackets because s1 is an array. You’re getting the string with the \n and spaces because its first value is the string representation of yet another array, s0.
So, if you’re just trying to format a string, s0, you can do:
let s0: String = "abcdef"
let s1: String = String(format: "It is ‘%#’", s0)
Or, if you really want an array of strings, you can call String(format:) for each using the map function:
let s0: [String] = ["abcdef", "ghijkl"]
let s1: [String] = s0.map { String(format: "It is ‘%#’", $0) }
By the way, in the examples above, I didn’t use a string format of just %#, because that doesn’t accomplish anything at all, so I assumed you were formatting the string for a reason.
FWIW, we generally don’t use String(format:) very often. Usually we do “string interpolation”, with \( and ):
let s0: String = "abcdef"
let s1: String = "It is ‘\(s0)’"
Get rid of all the unneccessary arrays and let the compiler figure out the types:
let s0 = "abcdef" // a string
let s1 = String(format:"- %# -",s0) // another string
print(s1) // prints "- abcdef -"
I'm trying to remove the last numbers of an IP address string in Swift so I can loop through IP addresses. For instance if my variable = 192.168.1.123, I would like to trim the string to equal 192.169.1.
I'm not sure how to do this since some IP addresses will end in 1, 2 or 3 digits. I couldn't figure out how to trim back to a certain character.
I have a solution (In your case only). You can try it
let str = "192.168.1.123"
var arr = str.components(separatedBy: ".")
arr.removeLast()
let newstr = arr.joined(separator: ".") + "."
You can find the range of the last .:
let ip = "192.168.1.123"
let lastdot = ip.range(of: ".", options: .backwards)!
let base = ip[...lastdot.lowerBound]
This code assumes there is at least one . in the string. If not it will crash. That is easily fixed with proper use of if let.
base will be a Substring so depending on what you do next, you may need to wrap that as:
let base = String(ip[...lastdot.lowerBound])
Whether explicitly converting to String depends on whether subsequent methods require String or StringProtocol. Converting to String copies over the storage again, which is costly and unnecessary for many operations, but may be required in some cases.