Objective C Array of Array of Strings - objective-c

I'm trying to make an array of array of strings so that I can eventually pull out something like ArrayOfArrays[0][1] = "hi".
NSString *ArrayOne[] = {#"hello", #"hi"};
NSString *ArrayTwo[] = {#"goodbye", #"bye"};
NSArray *ArrayOfArrays[] = {#[*ArrayOne, *ArrayTwo]};
However when I try to do this, I get an error: Initializer element is not a compile-time constant.
I've read that this is because I'm creating an array with dynamic values, though it should be static. Not sure how to work around this.
Any advice on making an array of array of strings?

Use NSArray, or rather NSMutableArray if you want to modify it after creation:
NSMutableArray *arrayOne = [#[#"hello", #"hi"] mutableCopy];
NSMutableArray *arrayTwo = [#[#"goodbye", #"bye"] mutableCopy];
NSMutableArray *arrayOfArrays = [#[arrayOne, arrayTwo] mutableCopy];
There are other ways to initialise it, but this is the only way that allows you to use Objective-C literal syntax.
You cannot store plain ol' C arrays within an Objective-C collection class as your code attempts to do.

You wrote:
it should be static
if this is what you want then your use of C arrays is quite valid, you just got the syntax wrong. You can use:
NSString *arrayOfArrays[][2] =
{ {#"hello", #"hi"},
{#"goodbye", #"bye"},
};
Important: The 2 is the number of elements in the inner array, you do not change it when adding further pairs.
This will give you a compile-time static array.
If what you are making is a map from one word to another you might be better off with a dictionary, e.g.:
NSDictionary *wordMap =
#{ #"hello" : #"hi",
#"goodbye" : #"bye"
};
and accessing an element becomes:
wordMap[#"hello"];
Note: the dictionary "constant" here is actually executed code; the C array version can appear as a global or local initialiser, while the dictionary initialisation must be done in a method/function - but it can assign to a global.
HTH

NSArray *array = #[
#[[ #"hello", #"hi" ] mutableCopy],
#[[ #"goodbye", #"bye" ] mutableCopy],
];
NSLog(#"%# is short for %#", array[0][1], array[0][0]);
Output: hi is short for hello

Related

NSMutableArray addObject using value and key

I found some codes like this:
for (int i = 0 ; i < pinyin_array.count; i++) {
[pinyins_arr addObject:#{k_PINYIN : pinyin_array[i]}];
}
where pinyins_arr is a NSMutableArray and Kk_PINYIN is a NSString. I am not sure if this is correct or not. I think it should be a NSMutableDictionary to add object of key and value pair. If this is true, the same key will be used for multiple values, what is the final array like?
The #{} syntax is shorthand for creating an NSDictionary. The second line could be verbosely re-written as:
[pinyins_arr addObject:[NSDictionary dictionaryWithObject:pinyin_array[i]] forKey:k_PINYIN]
You are adding NSDictionary objects to your NSMutableArray, so you will have an array of dictionaries which all have the same key. It is correct, if this is what you want.
To say if it's correct or not is not black and white.
It's correct in that it's legal to store an array of dictionaries like this.
It's not correct as there is no need to use an array of dictionaries at all, as there is no variation in the dictionary keys; you may as well just store an array of the values, which is what pinyin_array is anyway.
Try this logic
NSObject *collectionIndexString = indexPath;
NSMutableDictionary *tempDict = [myNSMutableArray[row] mutableCopy];
tempDict[#"collectionIndex"] = collectionIndexString;// Setting Key and Value
[myNSMutableArray replaceObjectAtIndex:row withObject:tempDict];

Selector name for NSArray literal constructor, like #[]?

It's been a while since Clang added Objective-C literal syntax for NSDictionary, NSArray, NSNumber, and BOOL literals, like #[object1, object2,] or #{key : value}
I'm looking for the selector name associated with the array literal, #[].
I tried to find out using the following code for NSArray, but I didn't see a selector that seemed right.
unsigned int methodCount = 0;
Method * methods = class_copyMethodList([NSArray class], &methodCount);
NSMutableArray * nameOfSelector = [NSMutableArray new];
for (int i = 0 ; i < methodCount; i++) {
[nameOfSelector addObject:NSStringFromSelector(method_getName(methods[i]))];
}
#[] is not a method on NSArray, so you're not going to find it there.
The compiler just translates #[] into a call to [NSArray arrayWithObjects:count:]. As in it basically finds all the #[] and replaces it with [NSArray arrayWithObjects:count:] (carrying across the arguments of course)
See the Literals section here
#[] uses +arrayWithObjects:count:
Official Clang Documentation
Array literal expressions expand to calls to +[NSArray arrayWithObjects:count:], which validates that all objects are non-nil. The variadic form, +[NSArray arrayWithObjects:] uses nil as an argument list terminator, which can lead to malformed array objects.
When you write this:
NSArray *array = #[ first, second, third ];
It expands to this:
id objects[] = { first, second, third };
NSArray *array = [NSArray arrayWithObjects:objects count:(sizeof(objects) / sizeof(id))];

Object Class Array Casting for a Method in Objective C

I have an object Student with 4 attributes(age,name,department,surname).
and I create an array of that object like this;
Student students[10] blah blah init blah.
then i want to use an Student array as argument for a method;
-(void) displayStudentInArray : (????) studentarray atIndex: (int) index {.....}
'???' are my problem. what do i write there? i ve no idea.
need help. i m new on objective c.
Rather than using C notation the array should be made like this:
NSArray *studentArray = [[NSArray alloc] initWithObjects: student1, student2, student2, ..., nil];
In which case the parameter type will be NSArray
-(void) displayStudentInArray : (NSArray *)studentarray atIndex: (int) index {.....}
The preferred method for creating arrays is using NSArray (or NSMutableArray if you want to modify the array after it is created):
NSArray *array = [[NSArray alloc]initWithObjects:student1, student2...];
Then your method signature would be:
-(void)displayStudentInArray:(NSArray *)studentarray atIndex:(int)index
These answers are correct, but if you really want to use C notation, you just need to add another asterisk to denote a reference to another pointer:
- (void)displayStudentInArray:(Student**)studentArray atIndex:(int)index {
Student* firstStudent = studentArray[1];
//do what you want with the array
}
This is because C arrays are really just pointers to an address in memory. If you wanted a C array for a primitive, it would look like this:
int* arrayOfInts = malloc(yourSize * sizeof(int));
You have an array of objects, but the idea is just the same. You just add one more asterisk to denote that it's a pointer to a pointer to an object.
Student** students = ...
Just write
Student *tempStudent = (array)[0];

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 ) ;

elegant comparing strings in two NSArrays

Dear all. We have 2 arrays(currentCarriers and companyList with strings inside. A final solution have to be array, which exclude same string from first array.
Bellow is a my solutions, but probably two for loops is not like cocoa style. Maybe somebody can suggest something better?
for (NSString *carrier in currentCarriers) {
for (NSString *company in companyList)
{
if ([company isEqualToString:carrier]) [removedCompanies addObject:company]; }
}
NSMutableArray *companiesForAdd = [NSMutableArray arrayWithArray:companyList];
[companiesForAdd removeObjectsInArray:removedCompanies];
Turn one list into a mutable array and then use removeObjectsInArray:, as in:
foo = [NSMutableArray arrayWithArray:currentCarriers];
[foo removeObjectsInArray:companyList];
// foo now contains only carriers that are not in the company list.
Edit:
Alternative with set difference (but possible slower in most cases due to the copying/allocating):
NSMutableSet *foo = [NSMutableSet setWithArray:currentCarriers];
[foo minusSet:[NSSet setWithArray:companyList]];
This might be faster for bigger lists, but you lose the ordering (if any).
I suppose you can get rid of the inner loop using -containsObject: method of NSArray, something like
for (NSString *carrier in currentCarriers) {
if ([companyList containsObject:carrier])
[removedCompanies addObject:company];
}
NSMutableArray *companiesForAdd = [NSMutableArray arrayWithArray:companyList];
[companiesForAdd removeObjectsInArray:removedCompanies];
I can suggest two options
If you worry about performance, then you can sort arrays and then create a result in one pass.
If you don't worry, then just filter the currentCarriers using [companyList containsObject:]