我有一个数组,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]);
提前致谢!
答案 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 ];
}
平均5次运行
输入填充NSNumbers
。
最快的最小优化-Os
。