如何删除领先&在NSArray中跟踪NSString的空白?

时间:2012-02-15 10:27:45

标签: iphone objective-c nsstring nsarray

我有一个NSArray声明:

@property (nonatomic, strong) NSArray *arrayRefineSubjectCode;

我手动填写数组元素如下:

     arrayRefineSubjectCode = [NSArray arrayWithObjects:
                              @"  BKKC 2061",
                              @"   BKKS 2631   ",
                              @"BKKS 2381      ",
                              nil];

那么如何删除开始和结束的空格并使每个数组元素变为:

     arrayRefineSubjectCode = [NSArray arrayWithObjects:
                              @"BKKC 2061",
                              @"BKKS 2631",
                              @"BKKS 2381",
                              nil];

我尝试过使用“stringByTrimmingCharactersInSet:”但它只适用于NSString。有点困惑在这里。请帮忙......

6 个答案:

答案 0 :(得分:75)

NSArray和包含的NSString对象都是不可变的。没有办法改变你拥有的物体。

相反,你必须创建新的字符串并将它们放在一个新的数组中:

NSMutableArray *trimmedStrings = [NSMutableArray array];
for (NSString *string in arrayRefineSubjectCode) {
    NSString *trimmedString = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    [trimmedStrings addObject:trimmedString];
}
arrayRefineSubjectCode = trimmedStrings;

答案 1 :(得分:15)

阅读http://nshipster.com/nscharacterset/

  

NSString -stringByTrimmingCharactersInSet:是一个你应该知道的方法   用心。它经常通过NSCharacterSet   + whitespaceCharacterSet或+ whitespaceAndNewlineCharacterSet,以删除字符串输入的前导和尾随空格。

所以,在Swift 3中

let _ = " A B  C  ".trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) // A B  C

答案 2 :(得分:2)

SSToolkit为此a couple of nice categories编辑:链接已损坏且似乎不是in SSToolkit anymore

这是旧代码:

- (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]];
}

但是,不是使用不同的字符集多次剥离,而是创建要删除的所有字符集的并集可能更好。 NSMutableCharacterSet是你的朋友。

答案 3 :(得分:1)

尼古拉对这种可变性是正确的。所以解决问题最简单的方法就是定义

@property (nonatomic, strong) NSMutableArray *arrayRefineSubjectCode;

然后逐个插入字符串,例如

for ( int counter = 0 ; counter < 3 ; counter++ ) {
    NSMutableString *s = [NSMutableString stringWithFormat:@"   blah  "];
    [arrayRefineSubjectCode addObject:s];
    }

...在其中获得三个带有“blah”的元素。请注意,您不能将addObject添加到不可变的NSArray,只能添加到可变的NSMutableArray。

当然,你可能已经在某处拥有多余的空间。您必须制作这些字符串的可变(!)副本,并使用addObject将它们添加到arrayRefineSubjectCode数组中。您可以在将空格添加到数组之前或之后删除空格。

希望有所帮助。

只是想补充一句话。您可能想知道为什么要使用不可变对象。有几个原因,但如果你可以逃脱不可变,它们会导致更快的代码,复制很容易(只需将指针复制到保存数据的地址,因为数据不会改变),它是更可能是线程安全的。当然,要注意NSArray指向可变对象,如NSMutableString!

答案 4 :(得分:1)

从“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;
}

答案 5 :(得分:0)

否,复制并替换为:

- (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      "]);
}