storing an array - objective-c

I am trying to store the outcome of a string from the array hypothesis into myArray
am I doing anything wrong?
myArray = [NSString stringWithFormat:#"%#", hypothesis];
Update
NSMutableArray *myArray
NSMutableArray *urArray
// this is where my words are converted into strings. e.g. if I said "HELLO"
- (void) pocketsphinxDidReceiveHypothesis:(NSString *)hypothesis{
if (x==1){
// I am trying to store "HELLO" into myArray for comparison later.
myArray = [NSString stringWithFormat:#"%#", hypothesis];
// this would print "HELLO"
self.textview.text = [NSString stringWithFormat:#"You said %#",hypothesis];
}
else {
urArray = [NSString stringWithFormat:#"%#", hypothesis];
}
}
this is basically it. after that I will compare myArray == urArray in an ifelse statement.

Try...
myArray = [NSArray arrayWithObject:[NSString stringWithFormat:#"%#", hypothesis]];

Yes, you are doing several things wrong.
you have a method -pocketsphinxDidReceiveHypothesis which you have defined as taking a single argument of type NSString*, the argument is called hypothesis.
In your question you say
I am trying to store the outcome of a
string from the array hypothesis
Which suggests that you know hypothesis is an array, but we can't verify this as you don't show that piece of code.
hypothesis must be a String or an Array. It cannot be both, you cannot be unsure.
If hypothesis is a String, ie. if you do something like:
NSString *input = #"Hello World";
[foo pocketsphinxDidReceiveHypothesis: input];
Then these two lines make no sense:-
NSMutableArray *myArray = [NSString stringWithFormat:#"%#", hypothesis];
NSMutableArray *urArray = [NSString stringWithFormat:#"%#", hypothesis];
Because, well look..
NSString *hypothesis = #"Hello World";
newString = [NSString stringWithFormat:#"%#", hypothesis];
This code does nothing, hypothesis and newString are identical, as you haven't even provided any arguments for the format. [NSString stringWithFormat:#"%#", hypothesis] is no different to just using hypothesis. So what you actually have is
NSString *hypothesis;
NSMutableArray *myArray = hypothesis;
NSMutableArray *urArray = hypothesis;
This is broken, you cant assign a String to an Array (well, i'm fairly certain you don't mean to anyhow). To use an Array you must use of of the several Array creation methods to give you, well, an Array. A String isn't an Array and can't pretend to be one.
Now, apologies if hypothesis isn't a String but is infact an Array (it would have helped if you had shown that piece of code). If it is an Array, ie. you do something like this..
NSArray *input = [NSArray arrayWithObject:#"Hello World"];
[foo pocketsphinxDidReceiveHypothesis: input];
Then your method definition is broken because you have defined it as taking a String argument
- (void)pocketsphinxDidReceiveHypothesis:(NSString *)hypothesis
When you need it to take an Array argument
- (void)pocketsphinxDidReceiveHypothesis:(NSArray *)hypothesis
Then the following two lines make no sense:-
NSMutableArray *myArray = [NSString stringWithFormat:#"%#", hypothesis];
NSMutableArray *urArray = [NSString stringWithFormat:#"%#", hypothesis];
[NSString stringWithFormat:#"%#", hypothesis] is exactly the same as [hypothesis description], which returns a String, so what you are effectively doing is:
NSArray *hypothesis;
NSString *hypothesisDescription = [hypothesis description];
NSMutableArray *myArray = hypothesisDescription;
NSMutableArray *urArray = hypothesisDescription;
So again, assigning a String to an Array variable - almost certainly not going to do what you want or need.
If hypothesis is a String and you meant to add it to an array, you must first make sure the array is initialized (ie it has to be a valid array). Something like NSMutableArray *myArray = [[NSMutableArray alloc] init] will do the trick. Then you can use one of NSMutableArray's methods to store your String, eg. [myArray addObject:hypothesis].
If hypothesis is an Array would you like to store the it in myArray as is or would you first like to transform it into a String?
Then you go on to say:-
I will compare myArray == urArray in
an ifelse statement
Given the confusion surrounding the preceding code it is not clear why you want to do this or what you hope to achieve. You have nowhere included a description of what this code is supposed to do. It is not clear whether you are aware that two Arrays that contain identical objects are not == (as the are two different arrays and have their own identity), but two pointers to the same Array are ==, eg:
NSArray *aSimpleArray = [NSArray arrayWithObjects:#"one", #"two", #"three", nil];
NSArray *foo = aSimpleArray;
BOOL result = (aSimpleArray==foo); // These are equal, result is true
NSArray *anotherSimpleArray = [NSArray arrayWithObjects:#"one", #"two", #"three", nil];
BOOL result = (aSimpleArray==anotherSimpleArray); // These are not equal, result is false
So unless you want to test if you have two pointers to the same Array (and not just two arrays with the same objects) == probably doesn't do what you want. Note there are methods to help compare Arrays, such as -isEqualToArray, so that:
NSArray *aSimpleArray1 = [NSArray arrayWithObjects:#"one", #"two", #"three", nil];
NSArray *aSimpleArray2 = [NSArray arrayWithObjects:#"one", #"two", #"three", nil];
BOOL areEqual1 = aSimpleArray1==aSimpleArray2; // FALSE
BOO areEqual2 = [aSimpleArray1 isEqualToArray:aSimpleArray2]; // TRUE
In general you have to be familiar with the interfaces of all the objects you are going to use
http://developer.apple.com/library/ios/#documentation/cocoa/reference/foundation/Classes/NSArray_Class/NSArray.html
The Apple documentation is excellent but i recommend a good book. There are many posts about book recommendations on SO so i leave that to you. Otherwise Apple provides hundreds of simple sample projects that you should study.

Are you trying to add hypothesis to one of your arrays (i.e. your arrays are arrays of multiple hypotheses)? If so then you can use addObject:
[myArray addObject:hypothesis];
If the hypothesis string is actually supposed to represent the entire array then you'll need to explain how the elements are encoded into this string before we can help you.

I am trying to store the same text
that hypothesis is holding into
myArray.
In that case:
NSArray *myArray = nil;
…
myArray = [NSArray arrayWithObject:hypthesis];
But mainly I would suggest that you go through some good Objective-C tutorial, since you seem to be confusing many basic ideas and it’s hard to get somewhere without knowing the basics.

Related

Modify Object while Iterating over a NSMutableArray

I was trying to modify an object from an array while iterating over it and couldn't find a nice way of doing it... This is what I've done, is there a simpler way of doing this? I've been googling for while but I couldn't find anything...
NSMutableArray *tempArray = [[NSMutableArray alloc]init];
NSArray *days = [restaurant.hours componentsSeparatedByString:#","];
for (NSString *day in days) {
NSString *dayWithOutSpace = [day stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[tempArray addObject:dayWithOutSpace];
}
days = [NSArray arrayWithArray:tempArray];
Thanks!
As suggested by others there might be better ways to accomplish the exact task in the question, but as a general pattern there is nothing wrong with your approach - build a new array.
However if you need to modify a mutable array, say because multiple objects reference it, there is nothing wrong with that either - that is why it is mutable after all! You just need to use standard iteration rather than enumeration - the latter is just the wrong tool for the job. E.g.:
NSMutableArray *anArray = ...
NSUInteger itemCount = [anArray count];
for(NSUInteger ix = 0; ix < itemCount; ix++)
{
// read from anArray[ix] and store into anArray[ix] as required
}
The way you do it is OK, since you are not modifying the array you are looping through.
Here is another way, a little less intuitive and probably not faster:
NSArray* days = [[[restaurant.hours componentsSeparatedByString:#" "] componentsJoinedByString:#""] componentsSeparatedByString:#","];
Considering your hours string is like: 2, 5, 6, 7 etc. you can use the string as #", " directly.
NSArray *days = [restaurant.hours componentsSeparatedByString:#", "];
Maybe it is better to eliminate all white spaces before separation.
NSString *daysWithOutSpaces = [restaurant.hours stringByReplacingOccurrencesOfString:#"[\\s\\n]" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, restaurant.hours.length)];
NSArray *days = [daysWithOutSpaces componentsSeparatedByString:#","];

Check if NSString exists in custom object in NSArray

I have an NSArray with Store objects. Each Store object has two NSString objects; StoreID and Name.
I would like to check quickly if an ID exists in this NSArray with Store objects.
Example:
Store *s1 = [[Store alloc] init];
s1.name = #"Some Name";
s1.id = #"123ABC";
Store *s2 = [[Store alloc] init];
s2.name = #"Some Other Name";
s2.id = #"ABC123";
NSArray *array = [[NSArray alloc] initWithObjects:s1, s2, nil];
NSString *myIdOne = #"ABCDEF";
NSString *myIdTwo = #"123ABC";
BOOL myIdOneExists = ...?
BOOL myIdTwoExists = ...?
Its the ...? I need to figure out. I know I can do this using a for loop and break when found... but this seems to me like an nasty approach since the NSArray could contain thousands of objects,... theoretically.
So I would like to know about a better solution.
Here's the thing: No matter what solution you go with, it will more or less boil down to "loop over the array and return whether or not the object was found." There is no way to search an array more quickly than this unless very specific conditions are met (e.g. the array is already sorted by the value you're searching). You can use a predicate, you can use an enumerator, you can use fast enumeration or you can use a test block — under the hood, they all amount to "loop over the array and perform a test." That's just how arrays work.
If this is something you need to do often and performance is a problem with the naive solution, a sensible solution might be to cache your IDs in an NSSet. Sets are tuned for fast member detection, so you should be able to get your answer much more quickly than you could with an array.
My personal "loop-over-the-array" solution:
BOOL idExists = NSNotFound != [stores indexOfObjectPassingTest:^(Store *store, NSUInteger idx, BOOL *stop) {
return [store.id isEqualToString:#"whatever"];
}];
(Written in the browser, so, y'know, caveat compilor.)
Try this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K == %#",#"id", myID];
NSArray *filteredArray = [array filteredArrayUsingPredicate:predicate];
if (filteredArray.count > 0)
Store *store = [filteredArray objectAtIndex:0];
Simplest solution, just use KVC:
NSArray *results = [array valueForKey:#"id"];
BOOL myIdOneExists = [results containsObject:myIdOne];
BOOL myIdTwoExists = [results containsObject:myIdTwo];
-(BOOL) id:(NSString*) theId existsInArray:(NSArray*) theArray {
for (Store* theStore in theArray) {
if ([theStore.id isEqualToString theId]) {
return YES;
}
}
return NO;
}
Another approach is to implement the isEqual method in Store to compare IDs only. Then construct a dummy Store object with the ID you're looking for and use indexOfObject or containsObject, referencing your dummy Store object.

How do I add a character to an already existing string?

When I make:
NSString x = #"test"
How do I edit it so that it becomes "testing"?
And when I put:
NSMutableString x = [[NSMutableString alloc] initWithString:#"test"];
There is an error that says:
Initializer element is not a compile-time constant.
Thanks
When declaring NSMutableString, you missed the asterisk:
NSMutableString *x = [[NSMutableString alloc] initWithString:#"test"];
// Here --------^
With a mutable string in hand, you can do
[x appendString:#"ing"];
to make x equal testing.
You do not have to go through a mutable string - this will also work:
NSString *testing = [NSString stringWithFormat:#"%#ing", test];
You need to declare your NSString or NSMutableString as *x. These are pointers to objects.
To change a string in code is quite easy, for example:
NSString *test = #"Test";
test = [test stringByAppendingString:#"ing"];
And the value in test will now be Testing.
There are a lot of great NSString methods, both instance and class methods, for manipulating and working with strings. Check the documentation for the complete list!
if you want to add multiple or single strings to an existing NSString use the following
NSString *x = [NSString stringWithFormat:#"%#%#", #"test",#"ing"];

Initialize the empty string in ObjectC?

Someone use the following to initialize the NSstring
NSString *astring = [[NSString alloc] init];
I am wondering why not just use
NSString *atring = nil or NSString *astring = #""
There is no semantic difference between NSString *astring = [[NSString alloc] init]; and NSString *astring = #""; - but NSString *astring = nil; is completely different. The first two produce a reference to an immutable string value, the last indicates the absence of a value.
Whether the various ways of generating an zero-length string produce different objects is entirely an implementation detail. The code:
NSString *a = [[NSString alloc] init];
NSString *b = [NSString new];
NSString *c = #"";
NSString *d = [NSString stringWithString:#""];
NSLog(#"%p, %p, %p, %p, %p", a, b, c, d, #""); // %p = print the value of the reference itself
outputs (the exact values will vary):
0x7fff7100c190, 0x7fff7100c190, 0x1000028d0, 0x1000028d0, 0x1000028d0
showing only 2 zero-length string objects were created - one for #"" and one for alloc/init. As the strings are immutable such sharing is safe, but in general you should not rely on it and try to compare strings using reference comparison (==).
NSString *atring = nil
is different -- it's a nil pointer, not an empty string.
NSString *astring = #""
is almost the same, if you change it to something like
NSString* astring=[#"" retain];
It's one of the things that "don't matter"; he or she simply used one way. Probably for no particular reason at all.
NSString *atring = nil; is simply setting the pointer to nil and does nothing other than ensure that pointer is set to nil;
NSString *astring = #""; is a shorthand literal and is the equivalent of [NSString stringWithString:#""];
On another point I don't know why you would want to initialize a string to nothing if its not mutable since you won't be able to change it later without overriding it.

NSArray filled with bool

I am trying to create an NSArray of bool values. How many I do this please?
NSArray *array = [[NSArray alloc] init];
array[0] = YES;
this does not work for me.
Thanks
NSArrays are not c-arrays. You cant access the values of an NSArray with array[foo];
But you can use c type arrays inside objective-C without problems.
The Objective-C approach would be:
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:[NSNumber numberWithBool:YES]];
//or
[array addObject:#(NO)];
...
BOOL b = [[array objectAtIndex:0] boolValue];
....
[array release];
EDIT: New versions of clang, the now standard compiler for objective-c, understand Object subscripting. When you use a new version of clang you will be able to use array[0] = #YES
Seems like you've confused c array with objc NSArray. NSArray is more like a list in Java, into which you can add objects, but not values like NSInteger, BOOL, double etc. If you wish to store such values in an NSArray, you first need to create a mutable array:
NSMutableArray* array = [[NSMutableArray alloc] init];
And then add proper object to it (in this case we'll use NSNumber to store your BOOL value):
[array addObject:[NSNumber numberWithBool:yourBoolValue]];
And that's pretty much it! If you wish to access the bool value, just call:
BOOL yourBoolValue = [[array objectAtIndex:0] boolValue];
Cheers,
Pawel
Use [NSNumber numberWithBool: YES] to get an object you can put in the collection.