Going through Collection

Year ago, I had a post about iterating through collection. Today my colleague’s question gave me the idea about an example of using collection right. Let’s say we have a collection like NSArray that contains multiple NSString objects, we want to print them in lines includes the line number.

1. Hello
2. Big
3. Big
...
100. World

Easy problem, right? Let’s see we have some solutions:

NSArray *lines; // with initial content

// #1.
for (NSString *line in lines) {
    int index = [lines indexOfObject:line];
    printf("%d. %@", index, line);
}

// #2.
int index = 0;
for (NSString *line in lines) {
    index++;
    printf("%d. %@", index, line);
}

// #3.
for (int index = 0; index < [lines count]; index++) {
    NSString *line = [lines objectAtIndex:index];
    printf("%d. %@", index + 1, line);
}

What’s a best way? I can say #2 > #3 | #1.

About #3, you can refer to my post to know why we should use iterator instead of index while going through collection. Of course they perform same with NSArray but using iterator help us more easily use another collection type later. So #1 and #2 are usually better than #3. Why is #2 better than #1? The issue is:

/* #1. */ int index = [lines indexOfObject:line];
/* #2. */ index++;

#1 is O(n) while #2 is O(1). We can see #1 is more readable (a bit easier to understand than #2) but #2 has better performance.

You could see #1 is worser in some way. In case of duplicated strings in lines, you may also get wrong result (index is the first found): http://stackoverflow.com/questions/3167849/indexofobject-vs-indexofobjectidenticalto