简体   繁体   中英

Replacing multiple characters in NSString by multiple other characters using a dictionary

I would like to replace some characters in my string, by other characters, using a dictionary.

For instance, every "a" should be replaced by "1", and every "1" should be replaced by "9". What I don't want is every "a" to be replaced twice, ending up with a "9". Every character must be replaced just once.

I got this working using the following code, but I feel like it can be done more efficient. Is this really the best I can do, or can you help me improve my code?

NSDictionary *replacements = [NSDictionary dictionaryWithObjectsAndKeys:
                              // Object, Key,
                              @"1", @"a",
                              @"2", @"b",
                              @"3", @"c",
                              @"9", @"1",
                              @"8", @"2",
                              @"7", @"3",
                              nil];

NSString *string = @"abc-123";
NSMutableString *newString = [NSMutableString stringWithCapacity:0];

for (NSInteger i = 0; i < string.length; i++)
{
    NSString *c = [NSString stringWithFormat:@"%C", [string characterAtIndex:i]];
    id replacement = [replacements objectForKey:c];
    if (replacement != nil) {
        [newString appendString:replacement];
    } else {
        [newString appendString:c];
    }
}

NSLog(@"newString: %@", newString); // newString: 123-987 (Works!)

Just to be clear: This code is working for me, I just feel like it's very inefficient. I'm Looking for ways to improve it.

Thank you.

The following code is perhaps not much faster, but slightly simpler and shorter. It enumerates all characters of the string with a method that works correctly even with composed characters such as Emojis (which are stored as two characters in the string).

NSMutableString *newString = [string mutableCopy];

[newString enumerateSubstringsInRange:NSMakeRange(0, [newString length])
                  options:NSStringEnumerationByComposedCharacterSequences
               usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
       NSString *repl = replacements[substring];
       if (repl != nil) {
           [newString replaceCharactersInRange:substringRange withString:repl];
       }
}];

First Replace Every "1" by "9" and then Replace Every "a" by "1". Whats wrong with the logic ?

Your Dictionary is

@"1", @"a",
@"2", @"b",
@"3", @"c",
@"9", @"1",
@"8", @"2",
@"7", @"3",
nil

Replacing "1" by "9" will create

@"9", @"a",
@"2", @"b",
@"3", @"c",
@"9", @"9",
@"8", @"2",
@"7", @"3",
nil

and then Replacing "a" by "1" will create

@"9", @"1",
@"2", @"b",
@"3", @"c",
@"9", @"9",
@"8", @"2",
@"7", @"3",
nil

Do you want this as your Desired result ?

If ur rule is static like u said...i dont have sure if it is better

 NSString *string = @"abc-123"; NSMutableString *newString = [NSMutableString stringWithCapacity:0]; for (NSInteger i = 0; i < string.length; i++) { unichar cu = [string characterAtIndex:i]; if (cu >=97 && cu<=99){ cu -= 48; }else if (cu>=49 && cu<=51){ cu = cu+10-((cu-48)*2); } [newString appendString:[NSString stringWithFormat:@"%C",cu]]; } NSLog(@"newString: %@", newString); 

I'm using ASCII codes to match ur exactly rule.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM