Objective-C基于偶数/奇数索引将数组拆分为两个单独的数组

时间:2014-11-30 00:29:39

标签: objective-c arrays nsmutablearray

我有一个数组,NSMutableArray * stringArray看起来像这样

stringArray = 

[0]String1
[1]String2
[2]String3
[3]String4
[4]String5
[5]String6

我如何根据偶数/奇数索引将此数组拆分为两个数组?

示例:

NSMutableArray *oddArray = ([1], [3], [5]);

NSMutableArray *evenArray = ([0], [2], [4]);

提前致谢!

4 个答案:

答案 0 :(得分:5)

创建两个可变数组,在源数组上使用enumerateObjectsWithBlock:并检查idx % 2以将其放入第一个或第二个数组

使用三元运算符:

NSArray *array = @[@1,@2,@3,@4,@5,@6,@7,@8,@9,@10,@11,@12];
NSMutableArray *even = [@[] mutableCopy];
NSMutableArray *odd = [@[] mutableCopy];
[array enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL *stop) {
    NSMutableArray *evenOrOdd = (idx % 2) ? even : odd;
    [evenOrOdd addObject:object];
}];

如果您喜欢超紧凑代码,可以使用像

这样的三元运算符
[((idx % 2) ? even : odd) addObject:object];

如果要将数组拆分为N个数组,可以执行

NSArray *array = @[@1,@2,@3,@4,@5,@6,@7,@8,@9,@10,@11,@12];

NSArray *resultArrays = @[[@[] mutableCopy],
                          [@[] mutableCopy],
                          [@[] mutableCopy]];

[array enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL *stop) {
        [resultArrays[idx % resultArrays.count] addObject:object];
}];

在Objective-C类别中,您应该想到创建可重复使用的代码:

@interface NSArray (SplittingInto)
-(NSArray *)arraysBySplittingInto:(NSUInteger)N;
@end

@implementation NSArray (SplittingInto)
-(NSArray *)arraysBySplittingInto:(NSUInteger)N
{
    NSAssert(N > 0, @"N cant be less than 1");
    NSMutableArray *resultArrays = [@[] mutableCopy];
    for (NSUInteger i =0 ; i<N; ++i) {
        [resultArrays addObject:[@[] mutableCopy]];
    }

    [self enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL *stop) {
                                [resultArrays[idx% resultArrays.count] addObject:object];
                            }];
    return resultArrays;
}
@end

现在你可以做到

NSArray *array = [@[@1,@2,@3,@4,@5,@6,@7,@8,@9,@10,@11,@12] arraysBySplittingInto:2];

array包含

(
        (
        1,
        3,
        5,
        7,
        9,
        11
    ),
        (
        2,
        4,
        6,
        8,
        10,
        12
    )
)

答案 1 :(得分:3)

创建两个NSIndexSet,一个用于偶数索引,一个用于奇数,然后使用objectsAtIndexes:提取数组的相应切片。

答案 2 :(得分:1)

您可以通过以下方式实现这一目标: -

上面两个已经提到了第一个和第二个解决方案。以下是相同的实现: -

//First Solution
NSArray *ar=@[@"1",@"2",@"3",@"4",@"5"];
NSMutableArray *mut1=[NSMutableArray array];
NSMutableArray *mut2=[NSMutableArray array];
[ar enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL *stop) {
    if (idx%2==0)
    {
        [mut1 addObject:object];
    }
    else
    {
        [mut2 addObject:object];
    }
}];

//Second Solution
NSMutableIndexSet *idx1 = [NSMutableIndexSet indexSet];
NSMutableIndexSet *idx2 = [NSMutableIndexSet indexSet];
for (NSUInteger index=0; index <ar.count(); index++)
{
   if(index%2==0)
    {
        [idx1 addIndex:index];
    }
    else{
        [idx2 addIndex:index];
    }
}
NSArray *evenArr=[ar objectsAtIndexes:idx1];
NSArray *oddArr=[ar objectsAtIndexes:idx2];
NSLog(@"%@",evenArr);
NSLog(@"%@",oddArr);

答案 3 :(得分:0)

有一些时间进行基准测试,结果表明当输入数组超过1000万时,使用并行执行会更快。

这是并发解决方案,它枚举输入数组两次以防止输出数组上的竞争条件。

static NSArray * concurrent(NSArray *input) {
    NSUInteger capacity = input.count / 2;
    NSArray *split = @[
                       [NSMutableArray arrayWithCapacity:capacity],
                       [NSMutableArray arrayWithCapacity:capacity],
                       ];
    [split enumerateObjectsWithOptions:NSEnumerationConcurrent
                            usingBlock:^(NSMutableArray *output, NSUInteger evenOdd, BOOL *stop) {
                                [input enumerateObjectsUsingBlock:^(id object, NSUInteger index, BOOL *stop) {
                                    if (index % 2 == evenOdd) {
                                        [output addObject:object];
                                    }
                                }];
                            }];
    return split;
}

我认为这是最佳串行解决方案,因此我将其用于基准测试:

static NSArray * serial(NSArray *input) {
    NSUInteger capacity = input.count / 2;
    NSMutableArray *even = [NSMutableArray arrayWithCapacity:capacity];
    NSMutableArray *odd = [NSMutableArray arrayWithCapacity:capacity];

    [input enumerateObjectsUsingBlock:^(id object, NSUInteger index, BOOL *stop) {
        NSMutableArray *output = (index % 2) ? odd : even;
        [output addObject:object];
    }];
    return @[ even, odd ];
}

结果

  • 100万元素
    • 序列号: 54.081 ms
    • 并发: 65.958 ms (18%更糟)
  • 1000万元素
    • Serial: 525.851 ms
    • 并发: 412.691 ms 27%更好
  • 1亿元素
    • 序列号: 5244.798 ms
    • 并发: 4137.939 ms 27%更好

平均5次运行 输入填充NSNumbers
最快的最小优化-Os