web-dev-qa-db-fra.com

Comment supprimer les espaces de début et de fin de NSString dans un NSArray?

J'ai un NSArray déclaré comme tel:

@property (nonatomic, strong) NSArray *arrayRefineSubjectCode;

J'ai les éléments de tableau remplis manuellement comme ci-dessous:

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

Alors, comment puis-je supprimer les espaces de début et de fin et rendre chaque élément du tableau comme suit:

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

J'ai essayé d'utiliser "stringByTrimmingCharactersInSet:" mais cela ne fonctionne que pour NSString. Un peu confus ici. S'il vous plaît aider ...

40
shamsulfakhar

Les objets NSArray et contenus NSString sont tous immuables. Il n'y a aucun moyen de changer les objets que vous avez.

Au lieu de cela, vous devez créer de nouvelles chaînes et les placer dans un nouveau tableau:

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

Lire http://nshipster.com/nscharacterset/

NSString -stringByTrimmingCharactersInSet: est une méthode que vous devez connaître par coeur. Il est le plus souvent passé à NSCharacterSet + whitespaceCharacterSet ou + whitespaceAndNewlineCharacterSet afin de supprimer les espaces de début et de fin d'entrées de chaîne.

Donc, dans Swift 3

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

SSToolkit a quelques catégories de Nice pour cela: edit: le lien est cassé et il ne semble plus être dans SSToolkit .

C'est l'ancien 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]];
}

Toutefois, au lieu de supprimer plusieurs fois des jeux de caractères différents, il peut être préférable de créer une union de tous les jeux de caractères à supprimer. NSMutableCharacterSet est votre ami là-bas.

2
orkoden

Nikolai a raison sur la mutabilité. Donc, le moyen le plus facile de résoudre les problèmes est de définir 

@property (nonatomic, strong) NSMutableArray *arrayRefineSubjectCode;

puis insérez les chaînes une par une, par ex.

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

... pour obtenir trois éléments avec "bla" dedans. Notez que vous ne pouvez pas ajouterObject à un NSArray immuable, mais uniquement à un NSMutableArray mutable.

Bien sûr, vous pouvez déjà avoir les chaînes avec des espaces superflus quelque part. Vous devrez faire une copie mutable (!) De ces chaînes et les ajouter au tableau arrayRefineSubjectCode avec addObject. Vous pouvez supprimer les espaces avant ou après les avoir ajoutés au tableau.

J'espère que ça aidera un peu.

J'ai juste pensé à ajouter une dernière remarque. Vous pourriez vous demander pourquoi vous utiliseriez des objets immuables de toute façon. Il y a plusieurs raisons, mais si vous pouvez vous en sortir, vous obtenez un code plus rapide, la copie est facile (copiez simplement le pointeur sur l'adresse qui contient les données, car ces données ne changeront plus susceptibles d'être thread-safe. Bien sûr, faites attention avec un NSArray qui pointe sur des objets mutables comme NSMutableString!

1
markjs

Supprime les espaces blancs de début et les espaces de fin de "chaîne"

- (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
zumzum

Mutez non, copiez et remplacez oui:

- (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      "]);
}
0
Elise van Looij