我有一个包含单词和空格的字符串,"2h 3m 1s".我想从中提取2h
出来; 所以在第一空间之前得到一切.
var date = "1,340d 1h 15m 52s" // I want to extract "1,340d".
这样做的最佳做法是什么?什么子串函数是最好的方法?
如果你的字符串很重,componentsSeparatedByString()
往往会更快.
斯威夫特2:
var date = "1,340d 1h 15m 52s" if let first = date.componentsSeparatedByString(" ").first { // Do something with the first component. }
迅捷3/4:
if let first = date.components(separatedBy: " ").first { // Do something with the first component. }
在这种情况下,.componentsSeparatedByString(" ")
方法和方法都不characters.split(" ")
是"最佳方法".这两种方法都将遍历整个String
对象,并给出一个String
数组作为结果.只有在计算了数组之后,我们才提取该数组的第一个条目.如果我们处理一个巨大的字符串,在这种情况下这是非常不必要的,并且会导致不必要的开销.
相反,对于一个巨大的字符串,以下方法更喜欢:
let firstDateEntryFast = date.substringToIndex((date.rangeOfString(" ")?.first)!)
这将查找第一次出现的索引" "
,然后将子串从原始字符串的开始仅返回到第一次出现.也就是说,它永远不会调查或利用原始(在此上下文中:假设为大)字符串超出它们第一次" "
出现的点.
但是,您应该注意,由于强制解包(运算符(!)),如果字符串不包含任何实例,则会在运行时崩溃" "
.因此,为了保持安全,并遵循Swift的可选约定,请在if let
子句中使用它:
if let myRange = date.rangeOfString(" ") { let firstDateEntryFast = date.substringToIndex(myRange.first!) // at this point, you know myRange is non-empty, and hence, .first can be // force-unwrapped } else { let firstDateEntryFast = date // no " " separation, unexpected? -> action }
在我的第一个版本的答案中,split
可以作为替代(可比componentsSeparatedByString
):
var date = "1,340d 1h 15m 52s" let dateAsArray = date.characters.split(" ").map{ String($0) } let firstDateEntry = dateAsArray[0]
或者,跳过将它们全部存储在一个数组中并直接获取第一个条目
var date = "1,340d 1h 15m 52s" let firstDateEntryDirectly = String(date.characters.split(" ")[0])