How to count rows and columns C Array? - objective-c

I have function
- (void)sortColor:(int [3][3])colors
Are there any ways to count the rows and columns in Objective-C?
I know this is not an nsarray.I am wondering are there any simple way to count the row and col?
i got the col but row
col = sizeof(colors[0])/sizeof(*colors[0])
can anyone help?

Assuming that you consider the first array count the row, eg: int arr[# rows][# columns] = ...
This is what you are looking for:
int rows = sizeof(arr) / sizeof(*arr);
int columns = sizeof(arr[0]) / sizeof(*arr[0]);
Not that this will simply return the size of which you created the C array at, not the number of actually existing values. If that is your goal, you do indeed need to use a different structure than what you have outlined above.

Well, there is nothing like 2D array in objective-C or Swift. This is how you can simulate the behaviour though:
NSMutableArray *row1 = [NSMutableArray arrayWithObjects:#"1", #"2", nil];
NSMutableArray *row2 = [NSMutableArray arrayWithObjects:#"3", #"4", nil];
NSMutableArray *row3 = [NSMutableArray arrayWithObjects:#"5", #"6", nil];
NSArray *multiArray = #[row1, row2, row3];
NSInteger rowCount = multiArray.count;
NSInteger columnCount = row1.count; // believing each row object have same number of objects

You get the count of items in an NSArray by using the count method. Note that int arr[3][3] is not an NSArray, it's a standard C array. You generally can't get the count of standard C arrays, you have to keep track of it yourself.

Related

Xcode : Count elements in string array

Is there any quick way I can get the number of strings within a NSString array?
NSString *s[2]={#"1", #"2"}
I want to retrieve the length of 2 from this. I there something like (s.size)
I know there is the -length method but that is for a string not a string array.
I am new to Xcode please be gentle.
Use NSArray
NSArray *stringArray = [NSArray arrayWithObjects:#"1", #"2", nil];
NSLog(#"count = %d", [stringArray count]);
Yes, there is a way. Note that this works only if the array is not created dynamically using malloc.
NSString *array[2] = {#"1", #"2"}
//size of the memory needed for the array divided by the size of one element.
NSUInteger numElements = (NSUInteger) (sizeof(array) / sizeof(NSString*));
This type of array is typical for C, and since Obj-C is C's superset, it's legal to use it. You only have to be extra cautious.
sizeof(s)/sizeof([NSString string]);
Tried to search for _countf in objective-c but it seems not existing, so assuming that sizeof and typeof operators works properly and you pass valid c array, then the following may work.
#define _countof( _obj_ ) ( sizeof(_obj_) / (sizeof( typeof( _obj_[0] ))) )
NSString *s[2]={#"1", #"2"} ;
NSInteger iCount = _countof( s ) ;

NSMutableArray contains Objects

I have to check whether an NSMutableArray contains an object multiple times (for e.g. the array contains 1,2,3,1,4), I want to know how many times 1 is present in the array. I am aware of containsObject: but how to use it for this kind of check?
NSCountedSet may help as you want to track how many times a duplicate value occurs.
http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSCountedSet_Class/Reference/Reference.html#//apple_ref/occ/cl/NSCountedSet
A quick way would be to convert it to an NSSet and then back to an array. NSSets cannot contain duplicates. Alternatively copy the values one by one into a new array using a loop, and each time check that the new array does not contain a copy of the object before adding it.
It depends on your object types, but if they can be used as keys for an NSDictionary, I would create an NSMutableDictionary that points to NSNumber objects containing counts for each object instance. Something like:
NSArray *array = whatever;
NSMutableDictionary *d = [NSMutableDictionary dictionaryWithCapacity:array.count];
for ( id obj in array )
{
NSNumber *number = [d objectForKey:obj];
if ( number == nil )
{
[d setObject:[NSNumber numberWithInt:1] forKey:obj];
}
else
{
[d setObject:[NSNumber numberWithInt:([number intValue]+1) forKey:obj];
}
}
At the end of this code, you are left with an NSDictionary where the keys are your original objects and the values are NSNumbers that contain the number of times that key exists in the original.

Sort 4 ints, smallest to biggest

Suppose I have 4 integers.
int a = 4;
int b = 2;
int c = 4;
int d = 1;
How can I sort these integers from smallest to biggest. The output needs to be something like this: d, b, a, c Most methods of sorting only give me the value of the sorted integer. I need to know the name.
Edit: Well, I'm writing an AI algorithm. I have 4 ints that store direction priority. (If the AI comes into a wall, it chooses the next best direction). So, I need to find the lowest int, and if the AI can't move that way, I choose the second to lowest etc.
There appears to be some confusion here; in your example a is not the "name" for the value 4, it is the name of an integer variable which currently contains 4. In other words "a" is not part of the data of your program.
What I assume you mean is you have name/value pairs which you wish to sort using the value as key. A common way to do this is to define a type for your pair, create a collection, and sort the collection.
In plain C you can declare:
typedef struct
{
char *name;
int value;
} MyPair;
You can create an array of these and sort it using standard C functions for array sorting, using just the value field as the key.
In Objective-C you can declare a class for your pair:
#interface MyPair : NSObject
{
NSString *name;
int value;
}
// methods/properties
#end
You can create an NSMutableArray of instances of MyPair and then sort the array, again you just use the value property (or instance variable) when doing the comparisons for the sort algorithm.
There are other variations of course. Once sorted you can iterate through the sorted array and display the name field/property.
Here is an objective-c approach. Unfortunately, you will not have the fun of writing the AI portion, the sorting is built into the libraries already.
int north = 1, south = 3, east = 2, west =4;
NSDictionary * nDict = [NSDictionary dictionaryWithObjectsAndKeys:#"north", #"name", [NSNumber numberWithInt:north], #"value", nil];
NSDictionary * sDict = [NSDictionary dictionaryWithObjectsAndKeys:#"south", #"name", [NSNumber numberWithInt:south], #"value", nil];
NSDictionary * eDict = [NSDictionary dictionaryWithObjectsAndKeys:#"east", #"name", [NSNumber numberWithInt:east], #"value", nil];
NSDictionary * wDict = [NSDictionary dictionaryWithObjectsAndKeys:#"west", #"name", [NSNumber numberWithInt:west], #"value", nil];
NSArray * toBeSorted = [NSArray arrayWithObjects:nDict,sDict,eDict,wDict,nil];
NSArray * sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"value" ascending:NO]];
NSArray * sorted = [toBeSorted sortedArrayUsingDescriptors:sortDescriptors];
NSLog(#"sorted %#", sorted);
Output
2012-01-23 19:50:21.079 TestEnvironment[19792:207] sorted (
{
name = west;
value = 4;
},
{
name = south;
value = 3;
},
{
name = east;
value = 2;
},
{
name = north;
value = 1;
}
)
Now you can check the highest priority by
NSString * highestPriority = [[sorted objectAtIndex:0] objectForKey:#"name"];
Now you have some classes you can look up (NSArray, NSDictionary, NSSortDescriptor, NSNumber)
You've tagged this Objective-C, but you haven't written anything that suggests using Objective-C. If you want to use Objective-C, I'd put the elements into an NSMutableArray (they'll need to be converted to NSNumbers to do that), and have the array sort them, as seen here.
If you just want to put them into a straight C array, you could sort them using heapsort (), qsort(), or mergesort().

How to use NSComparator?

I would like to know if the below question is possible using NSComparator or not?
I have two arrays; both hold data models. I have a property named rank in the data model. Now I want to compare both arrays and want to know if one of them holds higher ranked data models.
If Yes I would like to get NSComparisonResult = NSOrderedAscending.
By the way I'm using another approach here: is "total of each data Model's rank in array and if the total is greater than second array's data Model's total rank."
Yes, it would look something like this:
NSArray *someArray = /* however you get an array */
NSArray *sortedArray = [someArray sortedArrayUsingComparator:^(id obj1, id obj2) {
NSNumber *rank1 = [obj1 valueForKeyPath:#"#sum.rank"];
NSNumber *rank2 = [obj2 valueForKeyPath:#"#sum.rank"];
return (NSComparisonResult)[rank1 compare:rank2];
}];
(updated to show actually using the comparator)

iPhone, How can I store a value and a key and lookup by key and index?

I've tried NSMutableDictionary however I don't seem to be able to get an object by index.
Any ideas?
EDIT:
I've trying to create a uitableview sections object, which will store the header titles and be able to increment a counter for the rows. I need to be able to get the counter by index, counter value by title value.
Simplest way is to use 2 collections: dictionary for section infos (row numbers, countries etc) and array for section titles.
NSMutableDictionary *sectionInfos;
NSMutableArray *sectionTitles;
When you need a section info by sectionTitle:
NSDictionary *info = [sectionInfos objectForKey:sectionTitle];
int rowsCount = ((NSArray *)[info objectForKey:#"Countries"]).count;
When you need a section info by sectionIndex:
NSString *title = [sectionTitles objectAtIndex:sectionIndex];
NSDictionary *info = [sectionInfos objectForKey:title];
int rowsCount = ((NSArray *)[info objectForKey:#"Countries"]).count;
When you add a section, add sections info:
[sectionInfos setObject:info forKey:sectionTitle];
and a title to array, so infos and titles will be in sync.
[sectionTitles addObject:sectionTitle];
UPDATE: if the only info needed for section is number of rows:
UPDATE2: added types.
NSMutableDictionary *sectionRowCounts;
NSMutableArray *sectionTitles;
Rows count by sectionTitle:
int rowCount = [[sectionRowCounts objectForKey:sectionTitle] intValue];
Rows count by sectionIndex:
NSString *title = [sectionTitles objectAtIndex:sectionIndex];
int rowCount = [[sectionRowCounts objectForKey:title] intValue];
Adding a section:
[sectionRowCounts setObject:[NSNumber numberWithInt:rowCount] forKey:sectionTitle];
[sectionTitles addObject:sectionTitle];
Dictionaries are not ordered; therefore the objects in them do not have an index.
http://developer.apple.com/library/ios/#documentation/cocoa/reference/foundation/Classes/NSDictionary_Class/Reference/Reference.html#//apple_ref/occ/cl/NSDictionary
You need to use the key to retrieve a particular object from a dictionary. If you need to have the objects in a specific order, then you would probably use NSArray instead.
UPDATE
In your edit, you don't show what tableSectionArray is, but it looks like it's a dictionary (which makes it poorly named). You should use an NSArray, not an NSDictionary, to store what you want. If you need more than one value to be stored, then store an object that contains the values you need. Create a class that has the required values as properties; or, if appropriate, add NSDictionary objects to your array. (Based on how you are trying to assign an element from tableSectionArray, it looks like you do want it to contain dictionaries.) But you need the tableSectionArray itself to be an NSArray.
Yes, keep trying with NSMutableDictionary. It's the data structure you need for that. Can you post your code to see why it's not returning the value you expect?
Example:
NSString *yourvalue = #"Hello!";
NSMutableDictionary *d;
[d setValue:yourvalue forKey:#"yourkey"];
NSString *retrievedvalue = [d valueForKey:#"yourkey"];
// you should get value here