How to declare 2D array in Objective-C? - iphone

I am new to iPhone. I tried a lot to declare 2D array but I am unable to get the result.
NSMutableArray *outerarray = [[NSMutableArray alloc] init];
outerarray = [NSMutableArray arrayWithObjects:
[NSMutableArray arrayWithObjects:#"10-20","21-30","31-40","41-50","51-60","61-70","71-80","81-90","91-100",nil,
[NSMutableArray arrayWithObjects:#"10-20","21-30","31-40","41-50","51-60","61-70","71-80","81-90","91-100",nil],
nil];
I want to combine two arrays elements and compare it with other element.
Anyone can help me please?

#"..." is an NSString. "..." is not, it's a C string constant. You need to use the #"..." syntax for all NSString objects you're putting into an NSArray.

NS[Mutable]Array does not support 2D as far as I know. You can probably jury-rig it to mutate and access elements in 2D (make that its own class). Once you can access arbitrary elements, you can "combine" them and compare them as you need. The alternative is since Objective-C is a superset of C, its int arrayName [][] is available (but discouraged).

Related

NSMutableArray always empty

NSMutableArray *experienceValues;
experienceValues = [NSMutableArray alloc] initWithObjects:0,83,174,276,nil];
NSLog(#"%#", [experienceValues objectAtIndex:3]);
Why does this always throw -[__NSArrayM objectAtIndex:]: index 3 beyond bounds for empty array when it is clearly allocated and initialised in the line just before?
You need to wrap integer values like #0, #83, #174, ..., as primitive integers are no objects.
The NSMutableArray class as most of the collection classes in cocoa, accepts only objects. So if you want to put numbers, you can't put primitive type, but only instances of NSNumber class, thus:
[[NSMutableArray alloc] initWithObjects:[NSNumber numberWithInt:0]...etc
Or with literals:
[[NSMutableArray alloc] initWithObjects:#0,#83,#174,#276.. etc
The array is empty because the arguments are nil terminated and 0 is interpreted as nil.
The array should only contain objects (as opposed to primitives like ints). In you case you should create NSNumbers for all the numbers. You can do that with the number literal syntax #2.0.
Objective-C collection classes can only store objects; not primitives like int.
You need to wrap them in NSNumber objects.
If these are literal values then the answer provided by #Kirsteins demonstrates the syntax.
Try this
NSMutableArray *experienceValues = [[NSMutableArray alloc] initWithObjects:#0,#83,#174,#276,......., nil];
NSLog(#"%d", [experienceValues objectAtIndex:3]);
As initWithObjects: accepts only object you need to put only objects in it
You're trying to add integer value to NSArray.
NSMutableArray *experienceValues = [[NSMutableArray alloc] initWithObjects:[NSNumber numberWithInteger:42],nil];
then convert it back to integer like,
NSLog(#"%#", [experienceValues objectAtIndex:0]);

Setting Values in NSArray

Looked around for a while and couldn't find an answer to this, but it seems like a pretty simple thing. I want to create an NSArray that has room for 100 objects (Doors) and then just loop through to create a new door for each index in the array. I couldn't find a way to do this without manually writing the code for 100 new doors when I init the NSArray. I know I could do this by just creating an NSMutableArray and using addObject but I've heard NSArrays are much faster and I'd like to know how to do this for future reference.
Here's what I'm basically trying to do:
NSArray *doors = [[NSArray alloc]init]; //with size 100?
for (int i = 0; i < [doors count]; i++)
[[doors objectAtIndex:i] = [[Door alloc]init]];
if you are going to add objects to an array inside of a loop, then NSMutableArray is the correct object to use.
To create 100 doors:
NSMutableArray *doors = [NSMutableArray new];
for (int i=0; i < 100; i++){
[doors addObject:[[Door alloc]init]];
}
Now you have an mutable array with 100 Door Objects.
If you have no need to later modify the array, you can convert it back to
an immutable array for processing like this:
NSArray *newDoorList = [NSArray arrayWithArray:doors];
There may be some minor performance hits between mutable and non mutable arrays, but you will not notice them with just a few hundred objects - at least that has been my experience.
hope that helps. good luck.
Create an NSMutableArray and then use [array copy] to get a non-mutable NSArray.
See this answer for some options, basically create an NSMutable array and use that to create your NSArray...
http://www.cocoabuilder.com/archive/cocoa/190315-nsmutablearray-to-nsarray.html#190321
NSMutableArray is a dynamic array, and you don't need to predefine a size. As Aleph suggests, use an NSMutableArray and append your door object 100x. Like this:
NSMutableArray *myArray = [NSMutableArray arrayWithCapacity:100];
for ( int i = 0; i < 100; i++ ) {
[myArray addObject: [[Door alloc] init]];
}
NSArray *filledArray = [NSArray arrayWithArray:myArray];
Just edited to include the arrayWithCapacity: method. Per this SO thread, if you know the exact number you need, it should just allocate the memory all at once. Besides that, NSArray vs. NSMutableArray isn't going to show that much difference speed-wise. ( Until proven wrong. O_o )
Disadvantage of using NSMutableArray vs NSArray?

How can i add three objects into one in mutableArray in iphone application?

NSMutableArray * mutableArra = [[NSMutableArray alloc] init];
[mutableArra addObjectsFromArray:myArray];
NSLog(#"=====mutable aarrya ====::%#",mutableArra);
This is the result from the previous code:
01,12,2012
How can I add these three objects into one like the following?
01-12-2012
Thank you in advance.
I'm not sure how do you want to "add" those poor objects to one another, but if you want them to be concatenated as a string, try:
NSString *result = [myArray componentsJoinedByString:#"-"];
If this is for dates, I would recommend looking into NSDate which will do the formatting for you.

Convert NSString into NSMutableArray

I am trying to convert (or copy?) a NSString into a NSMutableArray. I guess my problem is that I don't really understand the structure of a MutableArray. In my limited knowledge, an Array could look like this:
NoteBook = [[NSMutableArray alloc] init];
for (int temp = 0; temp < 3; temp++) {
[NoteBook insertObject:#"Page" atIndex:temp];
}
Which would give me an Array of PagePagePage. Let's assume I wanted to open a txt file which contains PagePagePage, but the words were separated by a defined string so that I can keep the individual objects in my array apart, like so: Page--- end of page ---Page--- end of page ---Page.
Now, my next step would be to read this information from the txt file:
NSString *tempTextOut = [NSString stringWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:&error];
NoteBook = [tempTextOut componentsSeparatedByString: #"\n--- end of page ---\n"];
However, the last line does not work and I'm told by xCode: Incompatible Objective-C types assigning 'struct NSArray*', expected 'struct NSMutableArray*'. I don't really understand this - NSArray and MutableArray should be compatible (as one is the subclass of the other). Shouldn't xCode tell me that the problem is that I've been trying to convert a NSString into an NSMutableArray?
Would I perhaps need to re-set my MutableArray before putting something back into it, because right now, it still contains PagePagePage which I have assigned to it in the first step. I thought my NoteBook mutable array would simply be replaced by the string, but I guess that won't be the case.
I'd very much appreciate any help in this matter. Thanks!
componentsSeparatedByString: returns a plain immutable NSArray, not an NSMutableArray. You can pass the array to [NSMutableArray arrayWithArray:] or use mutableCopy on the array to get a mutable array from it, or you can use addObjectsFromArray: on an existing NSMutableArray to add objects to it.
If you go the mutableCopy route, do remember that you are responsible for calling release or autorelease on it.
Assigning a mutable object to the same immutable type will lead to runtime errors if you want to manipulate the immutable instance.
You can get your mutable copy by calling:
NoteBook = [[tempTextOut componentsSeparatedByString: #"\n--- end of page ---\n"] mutableCopy];
If NoteBook is a retained property you should assign to it this way:
self.NoteBook = [[[tempTextOut componentsSeparatedByString: #"\n--- end of page ---\n"] mutableCopy] autorelease];
so the mutable copy doesn't get over retained. You can release in your dealloc method then as normal.

How can i get Original order of NSDictionary/NSMutableDictionary?

i have created NSMutableDictionary with 10 keys.Now i want to access NSMutableDictionary keys in a same order as it was added to NSMutableDictionary (using SetValue:* forKey:* );
How can i achieve that ?
If you absolutely must use a dictionary container, you have to use a key that is sortable by the order in which you add key-value pairs. Thus, when creating your dictionary, you use a key that is an auto-incrementing integer or similar. You can then sort on the (integer) keys and retrieve the values associated with those keys.
If you do all of that, however, you may as well just use an NSMutableArray and add values to the array directly! It will be much faster and require less code. You just retrieve objects in order:
for (id obj in myArray) { /* do stuff with obj... */ }
NSMutableDictionary can't do that. Take a look at e.g. Matt Gallaghers OrderedDictionary.
I wrote a quick method to take a source array (of objects that are all out of order) and a reference array (that has objects in a desired (and totally arbitrary) order), and returns an array where the items of the source array have been reorganized to match the reference array.
- (NSArray *) reorderArray:(NSArray *)sourceArray toArray:(NSArray *)referenceArray
{
NSMutableArray *returnArray = [[NSMutableArray alloc] init];
for (int i = 0; i < [referenceArray count]; i++)
{
if ([sourceArray containsObject:[referenceArray objectAtIndex:i]])
{
[returnArray addObject:[arrReference objectAtIndex:i]];
}
}
return [returnArray copy];
}
Note that this is very fragile. It uses NSArray's containsObject: method, which ultimately will call NSObject's isEqual:. Basically, it should work great for arrays of NSStrings, NSNumbers, and maybe NSDates (haven't tried that one yet), but outside of that, YMMV. I imagine if you tried to pass arrays of UITableViewCells or some other really complex object, it would totally sh*t itself, and either crash or return total garbage. Likewise if you were to do something like pass an array of NSDates as the reference array and an array of NSStrings as the source array. Also, if the source array contains items not covered in the reference array, they'll just get discarded. One could address some of these issues by adding a little extra code.
All that said, if you're trying to do something simple, it should work nicely. In your case, you could build up the reference array as you are looping through your setValue:forKey:.
NSMutableArray *referenceArray = [[NSMutableArray alloc] init];
NSMutableDictionary *yourDictionary = [[ NSMutableDictionary alloc] init];
for (//whatever you are looping through here)
{
[yourDictionary setValue://whatever forKey:key];
[referenceArray addObject:key];
}
Then, when you want to loop over your items in the order they came in, you just
for (NSString *key in [self reorderArray:[myDict allKeys] toArray:referenceArray])
Actually you have a reference array in order manner then why you have to add to one more array.So i guess this approach is not good.Please consider my opinion.
Although #GenralMike 's answer works a breeze, it could be optimized by leaving off the unnecessary code as follows:
1) Keep an array to hold reference to the dictionary keys in the order they are added.
NSMutableArray *referenceArray = [[NSMutableArray alloc] init];
NSMutableDictionary *yourDictionary = [[ NSMutableDictionary alloc] init];
for (id object in someArray) {
[yourDictionary setObject:object forKey:someKey];
[referenceArray addObject:someKey]; // add key to reference array
}
2) Now the "referenceArray" holds all of the keys in order, So you can retrieve objects from your dictionary in the same order as they were originally added to the dictionary.
for (NSString *key in referenceArray){
//get object from dictionary in order
id object = [yourDictionary objectForKey:key];
}