NSMutableArray创建每两个对象的子数组,并在末尾注入一个空字符串

时间:2014-07-03 14:46:06

标签: ios objective-c arrays nsmutablearray nsarray

问题:这是效率最常用的方法吗?还是有更好的方式?

要求:创建一个包含唯一(非重复)子数组对象字符串对的新对象数组,最后注入一个空字符串。

假设在这种情况下我们有一个对象数组宠物名称(Harley,Jake,Levi,Zoe)

NSArray *objects = @[@"Harley",@"Jake",@"Levi",@"Zoe"];

NSMutableArray _petNames 我们将使用重新完成的对象数组填充它。我曾考虑使用 NSRange 来帮助构建子数组,但最终没有走那条路。

这是我的代码:

    //we need to add a blank string at the end of the array we created.
    //then we need to iterate over the array and make subArrays with every 2 objects in the array.
    BOOL addedDualArrayWithSpacer = NO;
    //build our array of pet names!
    if (!_petNames) {

        NSArray *dualArray = nil;
        _petNames = [[NSMutableArray alloc]init];
        for (NSInteger r = 0; r < [objects count] ; r++) {
            //[r , r+1] test for exsistence of r+1
            if ([objects containsObject:objects[r]] && ((r+1) < [objects count]) ) {

                NSLog(@"range is [%li] and max [%lu]", (long)r, (unsigned long)[objects count]);
                NSLog(@"exsists = %@ , %@", objects[r], objects[r+1]);

                dualArray = @[@[objects[r], objects[r+1]]];
                //test for exsistence of obj[r]
                if (([_petNames indexOfObject:objects[r]] == NSNotFound)
                    && (![_petNames containsObject:objects[r]])
                    ) {
                    //this will push the "range" out by one! thus hopping to the next correct item!
                    if((r+1) < [objects count]) r= r+1;
                    [_petNames addObjectsFromArray:dualArray];
                }
            }
            else{

                if (![_petNames containsObject:objects[r]]
                    && !([_petNames indexOfObject:objects] == NSNotFound)){
                    dualArray = @[@[objects[r], @""]];
                    addedDualArrayWithSpacer = YES;
                     [_petNames addObject:dualArray];
                }
            }
        }
        //now add blank object for ADD PET button if addedDualArrayWithSpacer is NO
        if (!addedDualArrayWithSpacer) {
            NSArray *cheat = @[@""];
            [_petNames addObject:cheat];
        }

此代码在控制台中输出此表单中的新_petNames数组(这是我需要的):

petnames [(         (         哈雷,         可靠的人     )         (         列维,         佐伊     )         (         &#34;&#34;     ) )]

我有一个过于复杂化代码的习惯,任何帮助提高效率都会受到高度赞赏。

2 个答案:

答案 0 :(得分:3)

我会这样做:

_petNames = [NSMutableArray arrayWithCapacity:[objects count] / 2 + 1];
BOOL isOddCount = [objects count] % 2;
// if there's an odd amount of objects in source array, we need to make one more iteration
// 'j' is the iteration counter
for (NSUInteger i = 0, j = 0, n = [objects count] / 2 + isOddCount; j < n; ++j, i += 2)
{
    NSMutableArray *subArray = [NSMutableArray arrayWithObject:objects[i]];
    [subArray addObject:j == n-1 && isOddCount ? @"" : objects[i+1]];
    [_petNames addObject:subArray];
}
if (!isOddCount)
    [_petNames addObject:@""];

如果源阵列中有奇数个对象,例如@[@"Harley",@"Jake",@"Levi",@"Zoe",@"Rex"],结果将是[((Harley,Jake),(Levi,Zoe),(Rex,“”))]。

P.S。在您的代码中,[objects containsObject:objects[r]]始终为true,([_petNames indexOfObject:objects[r]] == NSNotFound) && (![_petNames containsObject:objects[r]]中的两个条件都检查相同的内容,因此您可以轻松删除其中一个条件(同样适用于else分支)。

答案 1 :(得分:0)

我使用模运算符%和枚举。这里是基于块的枚举,因为它可以使索引自由,而在快速枚举(for (id obj in objects))中则需要昂贵的indexOfObject:。要删除重复的名称,我首先使用一组。

NSArray *objects = @[@"Harley",@"Jake",@"Levi",@"Zoe", @"Harley", @"Henry"];
objects = [[[NSOrderedSet alloc] initWithArray:objects] array];
NSMutableArray *petNames = [@[] mutableCopy];
[objects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    if (idx % 2 == 0) {
        [petNames addObject:[@[obj, @""] mutableCopy]];
    } else {
        [tempPetNames lastObject][1] = obj;
    }
}];

由于@""将在编译时创建一个对象,因此将它填充到数组中是一种便宜的操作,只是为了在大多数情况下覆盖它。


如果我理解你对唯一性的要求,我不确定。上面的代码将首先从名称中删除所有重复的代码,而以下代码将首先对它们进行配对,然后删除任何重复的对。

NSArray *objects = @[@"Harley",@"Jake",@"Levi",@"Zoe", @"Harley", @"Henry", @"Harley", @"Henry"];
NSArray *petNames;
NSMutableArray *tempPetNames = [@[] mutableCopy];
[objects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    if (idx % 2 == 0) {
        [tempPetNames addObject:[@[obj, @""] mutableCopy]];
    } else {
        [tempPetNames lastObject][1] = obj;
    }
}];
petNames = [[[NSOrderedSet alloc] initWithArray:tempPetNames] array];