I have an array, NSMutableArray *stringArray that looks like this
stringArray =
[0]String1
[1]String2
[2]String3
[3]String4
[4]String5
[5]String6
How would I go about splitting this array into two arrays based on even/odd indexes?
Example:
NSMutableArray *oddArray = ([1], [3], [5]);
NSMutableArray *evenArray = ([0], [2], [4]);
Thanks in advance!
create two mutable arrays, use enumerateObjectsWithBlock:
on the source array and check idx % 2
to put it into first or second array
Using the ternary operator:
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];
}];
If you like super compact code you could use the ternary operator like
[((idx % 2) ? even : odd) addObject:object];
If you want to split the array to N arrays, you can do
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];
}];
In Objective-C Categories should come to your mind to create re-uasable code:
@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
Now you can do
NSArray *array = [@[@1,@2,@3,@4,@5,@6,@7,@8,@9,@10,@11,@12] arraysBySplittingInto:2];
array
contains
(
(
1,
3,
5,
7,
9,
11
),
(
2,
4,
6,
8,
10,
12
)
)
创建两个NSIndexSet
,一个用于偶数索引,一个用于奇数,然后使用objectsAtIndexes:
来提取数组的相应切片。
There are following ways you can achieve that:-
The first and second one solution are already mentioned by the above two. Below are the implementation of the same:-
//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);
Got some time for benchmarking and it turns out that when the input array has more than 10 million , it's faster to use parallel execution.
Here is the concurrent solution that enumerates the input array twice to prevent race conditions on the output arrays.
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;
}
I consider this to be the best serial solution , so I used it for benchmarking:
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 ];
}
Average of 5 runs.
Input filled with NSNumbers
.
Fastest smallest optimization -Os
.
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.