Reputation: 563
I have an NSArray declared as such:
@property (nonatomic, strong) NSArray *arrayRefineSubjectCode;
I have the array elements manually filled out as below:
arrayRefineSubjectCode = [NSArray arrayWithObjects:
@" BKKC 2061",
@" BKKS 2631 ",
@"BKKS 2381 ",
nil];
So how do I remove starting and ending whitespace and make each array elements to become as these:
arrayRefineSubjectCode = [NSArray arrayWithObjects:
@"BKKC 2061",
@"BKKS 2631",
@"BKKS 2381",
nil];
I have tried using "stringByTrimmingCharactersInSet:" but it only works for NSString. Kinda confused here. Please help...
Upvotes: 44
Views: 36946
Reputation: 4232
Mutate no, copy and replace yes:
- (void)test_stringByTrimming
{
NSArray *arrayRefineSubjectCode = [NSArray arrayWithObjects:
@" BKKC 2061",
@" BKKS 2631 ",
@"BKKS 2381 ",
nil];
NSMutableArray *trimmedStrings = [NSMutableArray arrayWithArray:arrayRefineSubjectCode];
for (NSInteger i=0; i<trimmedStrings.count;i++) {
[trimmedStrings setObject:[[arrayRefineSubjectCode objectAtIndex:i] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] atIndexedSubscript:i];
}
XCTAssertTrue([[trimmedStrings objectAtIndex:0] isEqualToString:@"BKKC 2061"]);
XCTAssertTrue([[trimmedStrings objectAtIndex:1] isEqualToString:@"BKKS 2631"]);
XCTAssertTrue([[trimmedStrings objectAtIndex:2] isEqualToString:@"BKKS 2381"]);
XCTAssertTrue([[arrayRefineSubjectCode objectAtIndex:0] isEqualToString:@" BKKC 2061"]);
XCTAssertTrue([[arrayRefineSubjectCode objectAtIndex:1] isEqualToString:@" BKKS 2631 "]);
XCTAssertTrue([[arrayRefineSubjectCode objectAtIndex:2] isEqualToString:@"BKKS 2381 "]);
}
Upvotes: 0
Reputation: 48085
Read http://nshipster.com/nscharacterset/
NSString -stringByTrimmingCharactersInSet: is a method you should know by heart. It's most often passed NSCharacterSet +whitespaceCharacterSet or +whitespaceAndNewlineCharacterSet in order to remove the leading and trailing whitespace of string input.
So, in Swift 3
let _ = " A B C ".trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) // A B C
Upvotes: 16
Reputation: 20138
Removes leading white spaces and trailing white spaces from "string"
- (NSString*)stringByRemovingLeadingAndTrailingWhiteSpaces:(NSString*)string {
NSArray * components = [string componentsSeparatedByString:@" "];
if([components count] == 1) {
return string;
}
NSUInteger originalLength = [string length];
unichar buffer[originalLength+1];
[string getCharacters:buffer range:NSMakeRange(0, originalLength)];
NSMutableString * newStringNoLeadingSpace = [NSMutableString string];
BOOL goToStripTrailing = NO;
for(int i = 0; i < originalLength; i++) {
NSLog(@"%C", buffer[i]);
NSString * newCharString = [NSString stringWithFormat:@"%c", buffer[i]];
if(goToStripTrailing == NO && [newCharString isEqualToString:@" "]) continue;
goToStripTrailing = YES;
[newStringNoLeadingSpace appendString:newCharString];
}
NSUInteger newLength = [newStringNoLeadingSpace length];
NSMutableString * newString = [NSMutableString string];
unichar bufferSecondPass[newLength+1];
[newStringNoLeadingSpace getCharacters:bufferSecondPass range:NSMakeRange(0, newLength)];
int locationOfLastCharacter = (int)newLength;
for(int i = (int)newLength - 1; i >= 0; i--) {
NSLog(@"%C", bufferSecondPass[i]);
NSString * newCharString = [NSString stringWithFormat:@"%c", bufferSecondPass[i]];
locationOfLastCharacter = i+1;
if(![newCharString isEqualToString:@" "]) break;
}
NSRange range = NSMakeRange(0, locationOfLastCharacter);
newString = [[NSString stringWithString:[newStringNoLeadingSpace substringWithRange:range]] copy];
return newString;
}
Upvotes: 1
Reputation: 19996
SSToolkit has a couple of nice categories for this: edit: link is broken and it doesn't seem to be in SSToolkit anymore.
This is the old code:
- (NSString *)stringByTrimmingLeadingAndTrailingCharactersInSet:(NSCharacterSet *)characterSet {
return [[self stringByTrimmingLeadingCharactersInSet:characterSet]
stringByTrimmingTrailingCharactersInSet:characterSet];
}
- (NSString *)stringByTrimmingLeadingAndTrailingWhitespaceAndNewlineCharacters {
return [[self stringByTrimmingLeadingWhitespaceAndNewlineCharacters]
stringByTrimmingTrailingWhitespaceAndNewlineCharacters];
}
- (NSString *)stringByTrimmingLeadingCharactersInSet:(NSCharacterSet *)characterSet {
NSRange rangeOfFirstWantedCharacter = [self rangeOfCharacterFromSet:[characterSet invertedSet]];
if (rangeOfFirstWantedCharacter.location == NSNotFound) {
return @"";
}
return [self substringFromIndex:rangeOfFirstWantedCharacter.location];
}
- (NSString *)stringByTrimmingLeadingWhitespaceAndNewlineCharacters {
return [self stringByTrimmingLeadingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (NSString *)stringByTrimmingTrailingCharactersInSet:(NSCharacterSet *)characterSet {
NSRange rangeOfLastWantedCharacter = [self rangeOfCharacterFromSet:[characterSet invertedSet]
options:NSBackwardsSearch];
if (rangeOfLastWantedCharacter.location == NSNotFound) {
return @"";
}
return [self substringToIndex:rangeOfLastWantedCharacter.location + 1]; // Non-inclusive
}
- (NSString *)stringByTrimmingTrailingWhitespaceAndNewlineCharacters {
return [self stringByTrimmingTrailingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
However instead of stripping several times with different character sets, it might be better to create a union of all character sets you want removed. NSMutableCharacterSet
is your friend there.
Upvotes: 2
Reputation: 936
Nikolai is right about the mutability. So the probably easiest way to solve things is to define
@property (nonatomic, strong) NSMutableArray *arrayRefineSubjectCode;
and then insert strings one by one, e.g.
for ( int counter = 0 ; counter < 3 ; counter++ ) {
NSMutableString *s = [NSMutableString stringWithFormat:@" blah "];
[arrayRefineSubjectCode addObject:s];
}
... to get three elements with " blah " in it. Note that you cannot addObject to an immutable NSArray, only to a mutable NSMutableArray.
Of course, you may have the strings with superfluous spaces sitting around somewhere already. You'll have to make a mutable (!) copy of those strings, and add those to the arrayRefineSubjectCode array with addObject. You could remove the spaces before or after adding them to the array.
Hope that helps a bit.
Just thought to add a last remark. You might wonder why you'd use immutable objects anyway. There are a few reasons, but if you can get away with immutable, they result in faster code, copying is easy (just copy the pointer to the address that holds the data, because that data won't change anyway), and it is more likely to be thread-safe. Of course, be careful then with an NSArray that points at mutable objects like NSMutableString!
Upvotes: 1
Reputation: 81858
The NSArray
and the contained NSString
objects are all immutable. There's no way to change the objects you have.
Instead you have to create new strings and put them in a new array:
NSMutableArray *trimmedStrings = [NSMutableArray array];
for (NSString *string in arrayRefineSubjectCode) {
NSString *trimmedString = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
[trimmedStrings addObject:trimmedString];
}
arrayRefineSubjectCode = trimmedStrings;
Upvotes: 83