How to create a subarray of NSArray using NSRange? How to create a subarray of NSArray using NSRange? arrays arrays

How to create a subarray of NSArray using NSRange?


NSMakeRange is defined as (startingIndex, length), not (start, end) which it seems like how you are trying to use it.

So if you need the first 3 objects, then the rest it would look like this:

switch (section) {    case 0:        // This returns objects 0-2 in the array        return [array subarrayWithRange:NSMakeRange(0, 3)];    case 1:        // This returns objects 3-20 in the array        return [array subarrayWithRange:NSMakeRange(3, 17)];    default:        break;}

Edit: According to your comment, you are actually looking for the count to return in number of rows in section. Since you are using a fixed number of rows, you can just return the actual number within the case statement.

switch (section) {    case 0:        // This returns the count for objects 0-2 in the array        return 3;    case 1:        // This returns the count for objects 3-20 in the array        return 17;    default:        break;}

You do not actually need to use [subarrayWithRange], nor NSMakeRange. If you do need to at some point reference the actual array, you will get an NSIndexPath object which you can use to get the object from your array. You will need to use the section and row properties.

Edit: NSRange -> NSMakeRange


As others have noted you are using NSRange improperly.

It's definition is

typedef struct _NSRange {      NSUInteger location;      NSUInteger length;} NSRange;

so the second parameter of the struct is the length of the range, not the location of last element as you apparently think.


That being said, what you are doing it's much more complicated than it should be.

What's the purpose of producing a subarray of a known length and then returning the length of the subarray itself? With this in mind:

return [[array subarrayWithRange:NSMakeRange(3, 8)] count];

should be (using NSRange properly)

return [[array subarrayWithRange:NSMakeRange(3, 6)] count];

but it can actually be just

return 6;

or if the range length is a parameter

return length;

Again, there's no need in the world to slice an array and count. The length is known a priori.


So in the context of UITableViewDataSource, you have to

  • return the count for each section in -tableView:numberOfRowsInSection:. Something like

    switch(section) {    case 0: return 2;    case 1: return 18;}    
  • return the actual objects in tableView:cellForRowAtIndexPath:. Something like

    id object = nil;switch (indexPath.section) {    case 0:        object = self.objects[indexPath.row];        break;    case 1:        object = self.objects[2 + indexPath.row];        break;}...

As an extra tip, I would advice using a different notation for building structs

NSMakeRange(0, 42)

can be written

(NSRange){ .location = 0, .length = 42 }

which is much more readable (and less error prone, especially when you are in doubt about the meaning of the parameters).

Even

(NSRange){ 0, 42 }

is acceptable. I think it's better (and shorter) than NSMakeRange, but it loses the benefits or readability.


Ok I have solve my issue

In my Fetcher class I did

_sectionOne = [news objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 3)]];_sectionTwo = [news objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(3, 17)]];

then

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{    return 2;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    switch (section) {        case 0:            return [_sectionOne count];            break;        case 1:            return [_sectionTwo count];            break;        default:            break;    }    return 0;}

then in method cellForRowAtIndexPath:

 switch (indexPath.section) {        case 0:            item = [_sectionOne objectAtIndex:indexPath.row];            break;        case 1:            item = [_sectionTwo objectAtIndex:indexPath.row];            break;        default:            break;    }

item - it's my NSObject with MVC

So It's working As I wanted :)

Thanks for all trying to help me.

Cheers