Swift: Test boundary of String.Index for substring function

匿名 (未验证) 提交于 2019-12-03 02:33:02

问题:

Wow. Swift makes it really fiddly to copy a substring from a simple String.

Most programming languages allow characters to be simply indexed by their integer position in the string, making targeting a character or a range a matter of simple maths. Because Swift allows a wide range of characters to be used with various bit depths, a precise (memory?) index for each character has to be found first, based its position from the start or end of the string. These positions can then be passed into a method of the String class that returns the substring in the range. I've written a function to do the work:

//arguments: The parent string, number of chars from 1st char in it and total char length of substring  func subStr(str: String, c1: Int, c2: Int) -> String {     //get string indexes for range of substring based on args     let ind1 = str.startIndex.advancedBy(c1)     let ind2 = str.startIndex.advancedBy(c1+c2) //calls substring function with a range object passed as an argument set to the index values     let sub = str.substringWithRange(Range<String.Index>(start: ind1, end: ind2)) //substring returned     return sub } 

The problem is that because the substringWithRange function only works with Range objects its not obvious how to check if the substring is out of bounds of the string. For example calling this function would produce an error:

subStr ("Stack Overflow", c1: 6, c2: 12) 

The c1 argument is OK but the length of the (c2) substring exceeds the upper boundary of the parent string causing a fatal error.

How do I refine this function to make it handle bad arguments or otherwise refine this clunky process?

Many thanks for reading.

回答1:

You can use

let ind1 = str.startIndex.advancedBy(c1, limit: str.endIndex) let ind2 = str.startIndex.advancedBy(c1+c2, limit: str.endIndex) 

to advance the start index by the given amounts, but not beyond the end index of the string. With that modification, your function gives

subStr ("Stack Overflow", c1: 6, c2: 12) // "Overflow" subStr ("Stack Overflow", c1: 12, c2: 20) // "" 


回答2:

I quickly made a nice substring function for Strings without Foundation dependency:

extension String {     func substring(from from: Int, length: Int) -> String {         return String(characters.dropFirst(from).prefix(length))     } } 

If the length is bigger than possible, it just gives all the characters to the end. Can't crash Can't crash as long as neither argument is negative (it makes sense to crash if any argument is negative since that would be a major flaw in your code).

Example usage:

"Stack Overflow".substring(from: 6, length: 12) 

gives

"Overflow" 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!