Objective-C: using if/else statement with Plist values - iphone

I'm sure this is really basic but I can't see what I'm doing wrong. Can someone help me understand where I'm going wrong please? I'm working in xcode. I'm trying to make different parts of my view appear depending on values saved in a property list. If the value assigned to a particular UITextField is equal to zero then I want to hide that UITextField. I'm trying to do this like this. gross is the name of a UITextField:
NSArray *array = [[NSArray alloc] initWithContentsOfFile:filePath];
gross.text = [array objectAtIndex:7];
if ([array objectAtIndex:7 == 0]) {
gross.hidden = YES;
}
else {
gross.hidden = NO;
}
[array release];
I think the problem is something to do with how I've wrote the if/else statement. I know this is really basic but I don't quite understand where I'm going wrong. So Your help is much appreciated.

Code should read:
NSArray *array = [[NSArray alloc] initWithContentsOfFile:filePath];
gross.text = [array objectAtIndex:7];
if ([[array objectAtIndex:7] isEqualToString:#"0"]) {
gross.hidden = YES;
} else {
gross.hidden = NO;
}
[array release];
This assumes that the object at index 7 of your array exists and is a string. If it's actually an NSNumber, then you should instead use the conditional
if ([[array objectAtIndex:7] intValue] == 0) {
Note the above line works for a string where the text contains an int, such as #"0" or #"7".

if ([[array objectAtIndex:7] intValue] == 0)
First mistake is position of closing ]. And second one is you probably have NSString in array, as you have assigned that in text property. So you need to convert it to int by using intValue.

If your array contains nsstring then your condition should look like:
if ([[array objectAtIndex:7] intValue] == 0) {
...
or
if ([[array objectAtIndex:7] isEqualToString:#"0"]) {
1st condition will work also if your array contains NSNumbers (not likely in your case as you assign array elements to text property), but will fail if string is not a valid number - in that case intValue will return 0 as well.
2nd condition will work fine if you're sure that your elements are strings and you want to compare exactly with #"0".
Your condition is equivalent to
if ([array objectAtIndex:0])
because == operator has greater priority and evaluates to 0. Comparing array's element to 0 directly also does not make sense as NSArray cannot contain nil objects anyway

It might be easier to get the length of the array first and make sure that it has enough elements and then start accessing the elements themselves.

Related

Condition always fails though the comparative values seems correct in iOS

When I check the value of number in nslog it shows '0'
NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
NSNumber *number=[data objectForKey:#"serial"];
NSLog(#"%#",number);
if(number ==0 )
{
imgButton.hidden=YES;
}
But the condition always fails , I also changed the code like this
NSString *number=[data objectForKey:#"serial"]
NSLog(#"%#",number);
if(number == #"0" )
{
imgButton.hidden=YES;
}
But here too the condition fail ,What is the issue with this?
In the first code you are checking a NSNumber, object, against an int.
The correct check is:
if([number intValue] == 0) {
imgButton.hidden = YES;
}
In the second code you are checking two NSString, but you have to use the "isEqualToString" method and not "==". The correct code is:
if([number isEqualToString:#"0"]) {
imgButton.hidden = YES;
}
NSNumber is an object, 0 is an integer (a primitive type). They will never be equal. But you can change the comparison like this [number intValue] == 0 and this will work when the value of your NSNumber is 0.
On the string comparison, you should use the method
isEqualToString:NSString *)string
for the comparison.
For NSNumbers its
isEqualToNumber:(NSNumber *)number
Because otherwise you arent comparing if they have the same value, but if they are stored in identical memory space.

How do I compare UITextfield input to different strings?

I want to compare the value of the input from a UITextfield to some other strings. Here's my guessing.
if ([textfield.text isEqualToString:#"First" || #"Second" || #"Third"]) {
// do something
}
Is there any better approach to this?
Put the ors in the right place:
if([textfield.text isEqualToString:#"First"] ||
[textfield.text isEqualToString:#"Second"] ||
[textfield.text isEqualToString:#"Third"])
In a situation where you have a series of objects such as your example, you would add then to an array and test its existence in the array:
Example
NSMutableArray *arr = [[[NSMutableArray alloc] init] autorelease];
[arr addObject:#"First"];
[arr addObject:#"Second"];
[arr addObject:#"Third"];
if ([arr containsObject:textField.text])
{
// do something
}
Add First, Secound and Third to an array and then
if([myarray containsObject:someObject]){
// I contain the object
}
This approach saves you time and code ;)

How do I find (not remove) duplicates in an NSDictionary of NSArrays?

The title pretty much says it all, but just to clarify: I have an NSMutableDictonary containing several NSMutableArrays. What I would like to do is find any value that is present in multiple arrays (there will not be any duplicates in a single array) and return that value. Can someone please help? Thanks in advance!
Edit: For clarity's sake I will specify some of my variables:
linesMutableDictionary contains a list of Line objects (which are a custom NSObject subclass of mine)
pointsArray is an array inside each Line object and contains the values I am trying to search through.
Basically I am trying to find out which lines share common points (the purpose of my app is geometry based)
- (NSValue*)checkForDupes:(NSMutableDictionary*)dict {
NSMutableArray *derp = [NSMutableArray array];
for (NSString *key in [dict allKeys]) {
Line *temp = (Line*)[dict objectForKey:key];
for (NSValue *val in [temp pointsArray]) {
if ([derp containsObject:val])
return val;
}
[derp addObjectsFromArray:[temp pointsArray]];
}
return nil;
}
this should work
If by duplicates you mean returning YES to isEqual: you could first make an NSSet of all the elements (NSSet cannot, by definition, have duplicates):
NSMutableSet* allElements = [[NSMutableSet alloc] init];
for (NSArray* array in [dictionary allValues]) {
[allElements addObjectsFromArray:array];
}
Now you loop through the elements and check if they are in multiple arrays
NSMutableSet* allDuplicateElements = [[NSMutableSet alloc] init];
for (NSObject* element in allElements) {
NSUInteger count = 0;
for (NSArray* array in [dictionary allValues]) {
if ([array containsObject:element]) count++;
if (count > 1) {
[allDuplicateElements addObject:element];
break;
}
}
}
Then you have your duplicate elements and don't forget to release allElements and allDuplicateElements.

NSMutableArray check if object already exists

I am not sure how to go about this. I have an NSMutableArray (addList) which holds all the items to be added to my datasource NSMutableArray.
I now want to check if the object to be added from the addList array already exists in the datasource array. If it does not exist add the item, if exists ignore.
Both the objects have a string variable called iName which i want to compare.
Here is my code snippet
-(void)doneClicked{
for (Item *item in addList){
/*
Here i want to loop through the datasource array
*/
for(Item *existingItem in appDelegate.list){
if([existingItem.iName isEqualToString:item.iName]){
// Do not add
}
else{
[appDelegate insertItem:item];
}
}
}
But i find the item to be added even if it exists.
What am i doing wrong ?
There is a very useful method for this in NSArray i.e. containsObject.
NSArray *array;
array = [NSArray arrayWithObjects: #"Nicola", #"Margherita", #"Luciano", #"Silvia", nil];
if ([array containsObject: #"Nicola"]) // YES
{
// Do something
}
I found a solution, may not be the most efficient of all, but atleast works
NSMutableArray *add=[[NSMutableArray alloc]init];
for (Item *item in addList){
if ([appDelegate.list containsObject:item])
{}
else
[add addObject:item];
}
Then I iterate over the add array and insert items.
Use NSPredicate.
NSArray *list = [[appDelegate.list copy] autorelease];
for (Item *item in addList) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"iName MATCHES %#", item.iName];
NSArray *filteredArray = [list filteredArrayUsingPredicate:predicate];
if ([filteredArray count] > 0) [appDelegate insertItem:item];
}
Did you try indexOfObject:?
-(void)doneClicked{
for (Item *item in addList){
if([appDelegate.list indexOfObject:item] == NSNotFound){
[appDelegate insertItem:item];
}
}
UPDATE: You have a logical mistake, not mistake in code. assume the first array is ['a', 'b', 'c'], and the second is ['a', 'x', 'y', 'z']. When you iterate with 'a' through the second array it won't add 'a' to second array in the first iteration (compare 'a' with 'a') but will add during the second (compare 'a' with 'x'). That is why you should implement isEqual: method (see below) in your 'Item' object and use the code above.
- (BOOL)isEqual:(id)anObject {
if ([anObject isKindOfClass:[Item class]])
return ([self.iName isEqualToString:((Item *)anObject).iName]);
else
return NO;
}
Have a look at NSSet. You can add objects and the object will only be added if the object is unique. You can create a NSSet from an NSArray or vise versa.
You can override isEquals and hash on the object so that it returns a YES / NO based on the comparison of the iName property.
Once you have that you can use...
- (void)removeObjectsInArray:(NSArray *)otherArray
To clean the list before adding all the remaining objects.
NR4TR said correctly but i think one break statement is sufficient
if([existingItem.iName isEqualToString:item.iName]){
// Do not add
break;
}
Convert Lowercase and Trim whitespace and then check..
[string lowercaseString];
and
NSString *trim = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
You compare the addList's first object and appDelegate.list's first object, if they are not equal, you insert the addList's object. The logic is wrong, you should compare one addList's object with every appDelegate.list's object.

how to detect if an array isnt empty?

I am trying to detect if an array isn't empty in order to be able to do a certain call.
I tried using if (![array ==nil]) however that doesn't compile.
I'm sure there is a really easy explanation to this.
Update
If array is empty I want to do this:
array = [[NSMutableArray alloc]init];
If it has an object I want to do this:
array = [[userDefaults arrayForKey:#"MyFavorites"] mutableCopy];
If you declared it but did not assign anything to it at all:
NSMutableArray *array;
Then the array will be nil, meaning it isn't there at all so you can't say if it's empty or not, so you can't check anything.
If you did assign something to it, and you want to find out if the existing array is empty or not, that would depend on how you created it first.
If the array was assigned from some convenience method, it's autoreleased, so just do this:
if ([array count] == 0) {
array = [[NSMutableArray alloc] init];
} else {
array = [[userDefaults arrayForKey:#"MyFavorites"] mutableCopy];
}
If the array was assigned from an init or copy method, or it was retained previously, store the count in a temporary variable, release the array and use the temporary variable to decide what to do:
NSInteger count = [array count];
[array release];
if (count == 0) {
array = [[NSMutableArray alloc] init];
} else {
array = [[userDefaults arrayForKey:#"MyFavorites"] mutableCopy];
}
In your case I'd always use without differentation
array = [[userDefaults arrayForKey:#"MyFavorites"] mutableCopy];
and set the default value in the user defaults to an empty array right away at program start before accessing the defaults (from Apple's example):
+ (void)initialize{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults = [NSDictionary
dictionaryWithObject:[NSArray array] forKey:#"MyFavorites"];
[defaults registerDefaults:appDefaults];
}
See Apple's doc on this.
Supposing you are talking about NSArray, if myArray has not been properly alloced+initialized (what you are trying to check) its reference will be nil, so you can do:
if(myArray) //or even if(myArray != nil) since myArray will be a pointer
{
//properly inizialized
}
else
{
//not properly inited
}
If it's been inited on the other hand, you can test its emptiness by checking the count property which returns the number of elements it contains
if([myArray > 0])
//there is at least one element
}
else
{
//no elements
}
you can use count function of NSArray. it will work on NSMutableArray too....
syntext will be,
int ct=[array count];
ct will have number of items in array.
if it us empty it will be Zero