7

Sorry for the simple question, but I am self taught and know that there are gaps in my education.

To print an array in objective C, I believe is:

NSLog(@"My array: %@", myArray);

How can I print an array of arrays?

Thanks

2
  • Do you mean an NSArray of NSArrays? Or do you mean something like const char stuff[3][2]? Because the two are very different things. Commented Jan 31, 2011 at 2:36
  • I meant an NSArray of NSArrays. Commented Feb 1, 2011 at 16:58

7 Answers 7

11

You want this:

for(NSArray *subArray in myArray) {
    NSLog(@"Array in myArray: %@",subArray);
}

This will work for an array that has arrays nested one level deep.

Sign up to request clarification or add additional context in comments.

1 Comment

Without looping. how do i access the array item directly? for example: char a[0] = 'x'; cout << a[0]; ?
5

You don't need to do anything different to log an array of arrays; the code exactly as you've written it will already show the contents of the sub-arrays.

That is, the following program:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSMutableArray *array = [NSMutableArray array];

    for (int i=0; i<5; ++i) {
        NSMutableArray *sub = [NSMutableArray array];
        for (int j=0; j<=i; ++j) {
            [sub addObject:[NSString stringWithFormat:@"%d", j]];
        }
        [array addObject:sub];
    }

    NSLog(@"Array: %@", array);

    [pool drain];
    return 0;
}

Produces the following output:

Array: (
        (
        0
    ),
        (
        0,
        1
    ),
        (
        0,
        1,
        2
    ),
        (
        0,
        1,
        2,
        3
    ),
        (
        0,
        1,
        2,
        3,
        4
    )
)

Clearly, it's already logging the sub-arrays just fine. If you want to control the formatting differently, you'd have to manually iterate them, but by default, the -description of an NSArray is little more than the -description of every object in that array, which includes all sub-arrays.

1 Comment

This is by far the best answer, as it is the simplest. If you have custom objects in the arrays, you can always override NSObject's -description method to make it something more appropriate for that class.
2

So I was embarrassed by the recursiveDescription thing, so I wrote my own as a category on NSArray. Note that this code will print out a description for an array of arrays to any depth. The description itself could probably use a bit more formatting than commas and newlines. Here you go:

@interface NSArray (RecursiveDescription)
- (NSString *)recursiveDescription;
@end


@implementation NSArray (RecursiveDescription)

- (NSString *)recursiveDescription {
    NSMutableString *description = [[NSMutableString alloc] initWithString:@"Array (\n"];
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    for (NSObject *child in self) {
        if ([child respondsToSelector:@selector(recursiveDescription)]) {
            [description appendFormat:@"%@,\n", [child recursiveDescription]];
        }
        else {
            [description appendFormat:@"%@,\n", [child description]];
        }
    }
    [pool drain];
    [description appendString:@"\n)"];
    return [description autorelease];
}

@end

Comments

0

Try logging the return value from NSArray's -description method.

NSLog(@"My array: %@", [myArray description]);

1 Comment

That will be the same. The %@ format specifier uses the result of the description method (or CFCopyDescription() for CoreFoundation objects).
0

Moreover, for print all of elements

int i = 0;
int j = 0;
for(NSArray *subArray in myArray) {
    NSLog(@"[%d] %@",i, subArray);

    j =0;
    for(NSObject *element in subArray) {
        NSLog(@"[%d:%d] %@", i,j,element);
        ++j;
    }
    ++i;
}

Comments

0

As much as I like how easy it is to log out an object in Objective-C, I didn't like seeing a 2D array as a very long list. I created a category on NSArray that prints out 2D arrays. It's not perfect and can be improved, but it has worked for me.

Header:

@interface NSArray (Logging)

- (void)log2DArray;

@end

Implementation:

#import "NSArray+Logging.h"

@implementation NSArray (Logging)

- (void)log2DArray {
    NSMutableString *formattedString = [[NSMutableString alloc] init];
    NSInteger longestSubarrayLength = 0;
    for (NSArray *subarray in self) {
        if (subarray.count > longestSubarrayLength) {
            longestSubarrayLength = subarray.count;
        }
    }

    for (int i = 0; i < longestSubarrayLength; i++) {
        [formattedString appendFormat:@"\n"];

        for (int j = 0; j < self.count; j++) {
            NSArray *tempArray = [self objectAtIndex:j];
            if (tempArray.count <= longestSubarrayLength) {
                [formattedString appendFormat:@"%@\t", [tempArray objectAtIndex:i]];
            } else {
                [formattedString appendFormat:@"\t"];
            }
        }
    }

    NSLog(@"%@", formattedString);
}

@end

Usage:

[myArray log2DArray];

Comments

-3

Or use recursiveDescription :)

NSLog(@"my arrays: %@", [myArray recursiveDescription]);

5 Comments

Where is this method documented?
It's not a documented method for NSArray because it doesn't work.
sorry, to my & googles knowledge that's just a plain wrong answer. I had to downvote. I'll change that if you can provide some explenation..
My bad. This is an undocumented method on UIView to dump a description of a uiview and its children; I (mistakenly) assumed that the method works on all cocoa touch objects, but it's actually just UIViews. Sorry!
Adding a different answer and leaving this here as a warning that this undocumented method only applies to UIView.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.