tags:

views:

342

answers:

2

Given an NSMutableDictionary *dict, is this a bad way to replace keys with a new name? Is there an easier way?

NSArray *originalField = [NSArray arrayWithObjects:@"oldkey", @"oldkey2", nil];

NSArray *replacedField = [NSArray arrayWithObjects:@"newkey", @"newkey2", nil];

for (int i=0; i<[originalField count]; ++i)
{
    if ([dict objectForKey:[originalField objectAtIndex:i]] != nil) {
        [dict setObject:[dict objectForKey:[originalField objectAtIndex:i]] forKey:[replacedField objectAtIndex:i]];
        [dict removeObjectForKey:[originalField objectAtIndex:i]];
    }
}

Thanks!

+2  A: 

Nope, that's pretty much it. In general, you'd use fast enumeration and/or NSEnumerator to walk the arrays instead of going index-by-index, but since you're walking two parallel arrays, indexes are the clearest way to do it.

Peter Hosey
+2  A: 

That's not a bad way per se, but you could certainly make it more elegant (and in my opinion, easier) by cleaning up the code a bit and eliminating a few redundant method calls. As @Peter suggested, fast enumeration (you can use it on Leopard+ or iPhone) would be much quicker and cleaner, and therefore generally preferable. Here's an example:

NSArray *originalField = [NSArray arrayWithObjects:@"oldkey", @"oldkey2", nil];
NSArray *replacedField = [NSArray arrayWithObjects:@"newkey", @"newkey2", nil];
id anObject;
NSEnumerator *replacementKeys = [replacedField objectEnumerator];
for (id originalKey in originalField) {
    if ((anObject = [dict objectForKey:originalKey]) != nil) {
        [dict removeObjectForKey:originalKey];
        [dict setObject:anObject forKey:[replacementKeys nextObject]];
    }
}

One note of warning: you'll want to make sure that the arrays originalField and replacedField are the same length. If the latter is shorter, you'll get an exception, either from -[NSEnumerator nextObject] or -[NSArray objectAtIndex:]. If the latter is longer, you may wonder why some of the replacement keys are never used. You could use an NSAssert macro to verify that during debugging, and it will be disabled automatically in release builds.

Alternatively, if there is truly a one-to-one relationship between the keys, perhaps you could use a dictionary to map from old key to new key, and enumerate over the result of -[NSDictionary allKeys].

Quinn Taylor