Arrays in Objective-C - objective-c

If you want to use an array of characters/badguys is it better to have one array of badguy objects and each object have properties like Badguy1: color=blue, health=80. Then you loop through your array of characters and pull that information.... OR is it better to have multiple small arrays like character array, color array, health array and the index of all 3 arrays align to be the same character?
I know how to pull information from each array if it is separate but I do not know how to get the properties of each character if it is all wrapped up in 1 array.
I ask just because it seems like it would make more sense to use a single array and pull the parts that you need.

I know how to pull information from each array if it is separate but I do not know how to get the properties of each character if it is all wrapped up in 1 array. I ask just because it seems like it would make more sense to use a single array and pull the parts that you need.
You are correct in that it's generally smarter and a better design decision to keep related things together. If you'd like to store them this way, you can simply do:
// Get the character at index 3 in the "characters" array
// and print how many hit points it has left.
GameCharacter *ch = [characters objectAtIndex:3];
NSLog(#"This character has: %# hit points", ch.hitPointsRemaining);

Actually, now that I think about it. I guess I should just have an array of pointers and then get my values from the objects and not try to store all of that in the array.

Related

What is the fast way to find all anagrams inside an array in objective c?

I have an array that contains multiple words in there. The problem is asking me to find all the anagrams in there and pick out which one has the most anagrams. This is what I have so far:
Create a duplicate array of the old array.
Create an index array for the old array, to keep track of where every word is located. This index value won't be changed throughout the program
For the new array, I will be sort each individual word in the array.
For example: Before sorting, array has: [cat dog tac god act] then after that, it will have [act dgo act dgo act]
Sort the word in the array, then the array now will have: [act act act dgo dgo]. Now we can see that all anagrams has come together, but the order has changed in the the new array.
Use in the index array to keep track of the order of the words in the old array.
This approach seems to be good, but it depends on the number of the words that I have in the original array. If my original array is big enough, it could slow down the program due to copying process. Moreover, there is no way that I could keep track how many anagrams for each word. What could be the best approach to this kind of problem, consider that the array is big and the program has to find all the anagrams in a fast way ? Any help would be greatly appreciated. Thank you.
I think I would do something like this...
Create an NSCountedSet called anagramCounts. The objects in here will be a sorted array of letters.
Iterate your word array.
Turn each word into an array of letters.
Sort this array alphabetically.
Add the sorted array to the anagramCounts set.
After doing this the anagramCounts set will have all of the possible anagrams only once each and each will be stored next to a count of how many there are.
You can then get the object enumerator from this set and find the one with the highest count...
Or even... Add this to the previous list.
On the beginning
Create an NSInteger called highestAnagramCount and set it to 0.
Create an NSArray called mostCommonAnagram and leave it as nil.
...
On the end
Get [anagramCounts countForObject:sortedArray]; and if it is higher than highestAnagramCount then save this new value out and save the array.
At the end highestAnagramCount will tell you how many anagrams there are and mostCommonAnagram will contain the sorted array of letters.

Filling NSMutableArray for later use in obj-c

How do you fill a NSMutableArray with a set capacity for later use?
Basically I want to set up a NSMutableArray to act as a map for my game objects, so I have this line...
gameObjects = [[NSMutableArray alloc] initWithCapacity:mapWidth*mapHeight];
Which I had hoped would create and fill my MutableArray so I can get then access it with this kind of index...
int ii = (cellY*mapWidth)+cellX;
NSDictionary *currentObject = [gameObjects objectAtIndex:ii];
But I just learned initWithCapacity doesn't fill the array, so should I create blank objects to fill it with, or is there a Null that I can fill it with? Also would I do that with 2 for loops or is there an instruction something like "initWith:myObject" ?
I want to be able to check at a certain index within the array to see if there's an object there or not, so I need to be able to acces that index point, and I can only do that if there's something there or I get an out of bounds error.
I'll be using this NSMutableArray pretty much as a grid of objects, it's a 1 dimensional array organised as a 2 dimensional array, so I need to be able to fill it with mapWidth*mapHeight of something, and then calculate the index and do a check on that index within the array.
I've looked on here and googled but couldn't find anything like what I'm asking.
Thanks for any advice.
I think what you are looking for is [NSNull null]. It is exactly what you want- a placeholder value.
You can find more information on the topic in this question.
initWithCapacity is just a performance optimization -- it has no effect on the array behavior, it just keeps the code "under the covers" from having to repeatedly enlarge the internal array as you add more entries.
So if you want a "pre-allocated" array, you'd need to fill it with NSNull objects or some such. You can then use isKindOfClass to tell if the object is the right type, or simply == compare the entry to [NSNull null]. (Since there's only ever one NSNull object it always has the same address).
(Or you could use a C-style array of pointers with nil values for empty slots.)
But you might be better off using an NSMutableDictionary instead -- no need to pre-fill, and if the element isn't there you get a nil pointer back. For keys use a NSNumber object that corresponds to what would have been your array index.
initWithCapacity only hints to NSMutableArray that it should support this many objects. It won't actually have any objects in it until you add them. Besides, every entry in the array is a pointer to an object, not a struct like you'd normally have in a standard c array.
You need to change how you're thinking about the problem. If you don't add an object to the array, it's not in there. So either you pre-fill the array with "empty" objects as you've said, which is weird. Or you can add the objects as you need them.

ObjC: Best use an NSArray or NSDictionnary for this (zBuffer)?

Say I have a collection of "node" instances. An integer property call zIndex will be used to group them.
What are the pros/cons for storing them in :
1) An array of arrays
2) A dictionary of arrays
In pseudo code, I would describe the expected result like this:
zBuffer[100] = [node1, node 2];
zBuffer[105] = [playerNode, collectable1];
zBuffer[110] = [foreground1, foreground2];
And I'm wondering about what zBuffers should be; Must NSArrays only be used for sequential read/write? Like not using non-continuous indexes?
I tried with an NSMutableArray:
[zBuffer objectAtIndex:zOrder]
But it fails if the array contains no data for that index (like out-of-bound exception).
Thanks for your advices!
J
As far as I can see, one of your requirements is that the indexes you use to access zBuffer be not contiguous (100, 105, 100). In this case, I would not use an array for that, since the indexes you can use with an array must be less than the count of elements of the array (if you have 3 elements, then indexes range from 0 to 2).
Instead I would use NSMutableDictionary, where you can use the zIndex key as a "name" for groups of objects you are looking for.
This suggestion does not take into account any other requirements that you might have, especially concerning complexity and the kind of operations you are going to carry through on your collection of nodes (beyond accessing them through zIndex).
You could actually provide both. It looks like what you want to have is a sparse array: so you look up objects by index, but it's permissible for there not to be an object at a certain index. So you could make that.
I'd do that by creating an NSMutableArray subclass that implements the primitive methods documented. Internally, your subclass would use an NSMutableDictionary for storage, with numbers (the "filled" indices) as keys. -objectAtIndex: returns either the object with that number as its key or nil if the array is empty at that point.
There are some ambiguities in this use of the array contract that it's up to you to decide how to address:
does count return 1+(highest index in use), or the number of objects in the array?
the enumerator and fast enumeration patterns never expect to see nil, so you need to come up with an enumerator that always returns an object (but lets me see what index it's at) if you want users of your class to enumerator over the array.
you won't be able to initialise it with the +arrayWithObjects: (id) firstObject,... pattern of initialisers because they use nil as a sentinel.

taking out objects from NSMutableArray

I have an array which contains objects some may be same and some are different.
How can I take each same objects and different objects separately ?
Below is the array
NSMutableArray *items = [[NSMutableArray alloc]
initWithArray:[NSArray arrayWithObjects:#"rat", #"rat", #"cat",#"Lion", #"cat", #"dog", #"dog", nil]];
I want to have four arrays which will contains these items :
First array with two rats
2nd array with two cats
3rd array with one lion
4th array with two dogs
What could be the best way to take the objects out ? Identical object should be placed in same array.
Here's a general answer:
Put the array into an NSCountedSet - that will store each object and a count of the number of times it has been added.
Then - for each object in this counted set create an array with that object repeated according to the count of each object.
It will work in your case, because you are using static strings, which are going to be the same if they are the same string. This will take more work if you are using custom objects.
But the real question we have to ask is why you need to create these repetitive structures. If we could know what you are doing with it, we could give you better advice about how to go about it. For example, if you just need to keep a running count of the number of each type of object you have, you could just use the NSCountedSet directly (it descends from NSMutableSet, so it is already mutable) and not bother with creating the arrays.

can I sort NSMutable array of NSStrings by their substrings using the selector (in place)?

I have a NSMutableArray consisting out of NSStrings. When I need to sort it, I use [array sortUsingSelector:#selector(caseInsensitiveCompare:)] which works perfect.
But sometimes I need to sort the array by substrings of NSStrings. The substring is defined in this case as part of NSString following some marker. The thing is complicated further by the fact that marker can be positioned differently in every string.
Obviously I can break NSString into 2 objects and do sorting on them but it will require significant changes.
Is there a way to do the sorting using selector similar to what I have described above?
I think if not, then I might sort by creating a sorted copy of an array (instead of using selector to do it in place), then releasing the original.
You can perform any arbitrarily complex sorting inline with NSMutableArray's sortWithOptions:usingComparator:
[myMutableArray sortWithOptions:NSSortStable usingComparator:^NSComparisonResult(NSString* str1, NSString* str2) {
// Scan for your marker in both strings and split on it...
// Say you store the results in substr1 and substr2...
return [substr1 caseInsensitiveCompare:substr2];
}];