Re: Swift: How to determine if a Character represents whitespace?
Re: Swift: How to determine if a Character represents whitespace?
- Subject: Re: Swift: How to determine if a Character represents whitespace?
- From: Charles Jenkins <email@hidden>
- Date: Fri, 03 Apr 2015 16:18:58 -0400
So my Character.isMemberOfSet() is a poor general-purpose method, and I need to ditch it.
I like your code. I had to modify it a bit so it wouldn’t fall on strings composed entirely of whitespace:
let testString = " \n\n \t\t"
let attrStr = NSAttributedString( string:testString )
let str = attrStr.string as NSString
let notWhitespace = NSCharacterSet.whitespaceAndNewlineCharacterSet().invertedSet
var resultRange:NSRange
let startRange = str.rangeOfCharacterFromSet( notWhitespace, options:NSStringCompareOptions.allZeros )
if startRange.length > 0 {
let endRange = str.rangeOfCharacterFromSet( notWhitespace, options:NSStringCompareOptions.BackwardsSearch )
let startIndex = startRange.location
let endIndex = endRange.location + endRange.length
resultRange = NSRange( location:startIndex, length:endIndex - startIndex )
} else {
// String is empty or all whitespace
resultRange = NSRange( location:0, length:0 )
}
let resultStr = attrStr.attributedSubstringFromRange( resultRange )
So, even though attrStr.string returns an NSString, you have use the “as” to explicitly keep the type and be able to do math on range indexes. Lacking that cast is what made rangeOfCharacterFromSet() useless to me yesterday.
Your code seems way better. but is there a way in the playground for use to test addresses to make sure attrStr.string as NSString doesn’t perform a copy?
—
Charles
On April 3, 2015 at 2:04:01 PM, Quincey Morris (email@hidden) wrote:
On Apr 3, 2015, at 04:00 , Charles Jenkins <email@hidden> wrote:
for char in String( self ).utf16 {
if set.characterIsMember( char ) {
return true
}
Now we’re back to the place we started. This code is wrong. It fails for any code point that isn’t representable a single UTF-16 code value, and it fails for any grapheme that isn’t representable as a single code point.
This is what I would do (playground version):
import Cocoa
let notWhitespace = NSCharacterSet.whitespaceAndNewlineCharacterSet().invertedSet
let attrStr = NSAttributedString( string:" Fourscore and seven years ago... \n\n \t\t" )
let str = attrStr.string as NSString
let startRange = str.rangeOfCharacterFromSet(notWhitespace, options: NSStringCompareOptions.allZeros)
let endRange = str.rangeOfCharacterFromSet(notWhitespace, options: NSStringCompareOptions.BackwardsSearch)
let startIndex = startRange.length != 0 ? startRange.location : 0
let endIndex = endRange.length != 0 ? endRange.location + 1 : str.length
let resultRange = NSRange (location: startIndex, length: endIndex - startIndex)
let resultStr = attrStr.attributedSubstringFromRange (resultRange)
It’s the Obj-C code, just written in Swift. The ‘as NSString’ in the 3rd line makes it work.
The practical difficulty in your original approach is that (e.g.) String.rangeOfCharacterFromSet returns a Range<String.Index>, but AFAICT that isn’t convertible back to a NSRange, or even just integer indexes. At the same time, AFAICT it isn’t useful with a String because it doesn’t contain Character indexes, just unichar indexes, which have no meaning for a String in general.
Actually, my testing is with Swift 1.1, since I’m not in a position to move to Xcode 6.3 yet. It’s possible that the results are different in Swift 1.2. However, in the section of the release notes that talks about bridging between String and NSString, it says:
Note that these Cocoa types in Objective-C headers are still automatically bridged to their corresponding Swift type
so I suspect the results would be the same in 1.2. It seems to me there is an actual bug here:
“String methods corresponding to NSString methods that return NSRange values actually return Range<String.Index> values, but these are not valid ranges, either for String objects (they represent UTF-16 code value positions, not Character positions) or for NSString objects (they’re not convertible back to NSRange). The String methods ought to return NSRange values just like their NSString counterparts.”
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden