Как удалить начальные и конечные пробелы NSString внутри NSArray? - PullRequest
40 голосов
/ 15 февраля 2012

У меня есть 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 ]

75 голосов
/ 15 февраля 2012

NSArray и содержащиеся NSString объекты являются неизменяемыми.Невозможно изменить имеющиеся у вас объекты.

Вместо этого вам нужно создать новые строки и поместить их в новый массив:

NSMutableArray *trimmedStrings = [NSMutableArray array];
for (NSString *string in arrayRefineSubjectCode) {
    NSString *trimmedString = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    [trimmedStrings addObject:trimmedString];
}
arrayRefineSubjectCode = trimmedStrings;
15 голосов
/ 02 августа 2015

Чтение http://nshipster.com/nscharacterset/

NSString -stringByTrimmingCharactersInSet: метод, который вы должны знать наизусть.Чаще всего он передается NSCharacterSet + whitespaceCharacterSet или + whitespaceAndNewlineCharacterSet, чтобы удалить начальный и конечный пробелы строкового ввода.

Итак, в Swift 3

let _ = " A B  C  ".trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) // A B  C
2 голосов
/ 11 декабря 2013

SSToolkit имеет пару хороших категорий для этого: edit: ссылка не работает и больше не похоже на в SSToolkit .

Это старый код:

- (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 твой друг там.

1 голос
/ 07 октября 2014

Удаляет начальные и конечные пробелы из "строки"

- (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;
}
1 голос
/ 15 февраля 2012

Николай прав насчет изменчивости. Так что, вероятно, самый простой способ решить проблему - определить

@property (nonatomic, strong) NSMutableArray *arrayRefineSubjectCode;

, а затем вставьте строки одну за другой, например,

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

... чтобы получить три элемента с "бла" в нем. Обратите внимание, что вы не можете добавить объект к неизменяемому массиву NSArray, только к изменяемому массиву NSMutableArray.

Конечно, у вас могут быть строки с лишними пробелами, которые уже где-то сидят. Вам нужно будет сделать изменяемую (!) Копию этих строк и добавить их в массив arrayRefineSubjectCode с помощью addObject. Вы можете удалить пробелы до или после добавления их в массив.

Надеюсь, это немного поможет.

Просто подумал добавить последнее замечание. Вы можете спросить, почему вы все равно используете неизменяемые объекты. Есть несколько причин, но если вы можете избежать использования неизменяемого, это приведет к более быстрому коду, копирование будет легким (просто скопируйте указатель на адрес, содержащий данные, потому что эти данные в любом случае не изменятся), и это более вероятно, будет потокобезопасным. Конечно, будьте осторожны с NSArray, который указывает на изменяемые объекты, такие как NSMutableString!

0 голосов
/ 08 августа 2018

Изменить нет, скопировать и заменить да:

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