How do Arrays behave in Objective-C? - objective-c

I've always had my doubts about Arrays.
If an Array's count is 7, and I replace the SECOND elements with 'NULL', does it still have count 7?
If an Array's count is 7, and I replace the LAST elements with 'NULL', does it still have count 7? Or will it have count 6?
I need to know this behavior to make a function that removes the first element of the Array (place '0'), and the other elements of the Array swap one place to the front.
- (void) eat {
[foodArray replaceObjectAtIndex:0 withObject:NULL];
for (int i = 0; i<[foodArray count]-1; ++i){
[foodArray replaceObjectAtIndex:i withObject:[foodArray objectAtIndex:i+1]];
}
[foodArray replaceObjectAtIndex:[foodArray count]-1 withObject:NULL];
}
Would that work?
(Thanks!)
Edit: I've just noticed the first line isn't necessary, as I'm already replacing the first element later. Am I wrong?

If you want to remove an object from an array, just use [foodArray removeObjectAtIndex:]. The way you're doing it you're just leaving a null value in the array.

Just remove the item:
- (void) eat {
[foodArray removeObjectAtIndex:0];
}
Inorder to add/remove array elements the array must be mutable: NSMutableArray so foodArray must be a NSMutableArray.

Trying to keep NULL in an array is bad idea in general.
If you need to use some kind of placeholder - it's better to use an instance of NSNull class.
Later you can check type of the object using class name check:
if( [objectFromArray isKindOfClass:[NSNull class]] == YES )
{ // This is NSNull instance, not real object }

Related

objective-c , Finding objects from array

I have an array that contains some objects;
example:
NSArray*arr=[NSMutableArray arrayWithObjects:#1,#5,#7,#6 nil];
How I could find, for example if the array contains the number 1 and 7 without creating a loop.
Is there such a function?
For example returns a Boolean value or something?
Sure thing!
You can use this method
(BOOL)containsObject:(ObjectType)anObject;
or somethings else:
(NSUInteger)indexOfObject:(ObjectType)anObject;
(NSUInteger)indexOfObject:(ObjectType)anObject inRange:(NSRange)range;
Have fun.
Use indexOfObject to find if an element is present in your array or not :
NSNumber *num=[NSNumber numberWithInteger:7];
NSInteger anIndex=[myArray indexOfObject:num];
if(NSNotFound == anIndex) {
NSLog(#"not found");
}
Hope this helps.

NSMutable array count not changing after removed child

GMSprite *bulletMove;
int bulletCount = [bullets count];
for(int i = 0; i < bulletCount; i++)
{
if(bulletMove.position.x > 500)
{
[self removeChild:[bullets objectAtIndex:i] cleanup:YES];
}
}
How do i remove the child from the array and also the object in the array so that bulletCount goes down an integer and adjusts the array to the removed object
Use below code:
[bullets removeObjectAtIndex:i];
Get bullet object from bulet array and use below code.
[bullet removeFromParentAndCleanup:YES];
Use
[bullets removeObjectAtIndex:i];
How do i remove the child from the array and also the object in the
array so that bulletCount goes down an integer and adjusts the array
to the removed object
Using the above method will remove the object from index i and all following objects will shift one-up.
GMSprite *bulletMove;
for(int i = 0; i < [bullets count]; )
{
if(bulletMove.position.x > 500)
{
[bullets removeObjectAtIndex:i];
} else {
i++;
}
}
It is not exactly good style manipulating the index varialbe of a for loop within its body. You may want to re-structure this suggestions with antother type of loop (do-while or so). The basic idea is, however, that [bullest count] will always provide you with the current amount of entries in the array. And the index must only be increased if you do not remove the current object. If you remove it an your index is at 10 (example) then the next one to be checkt is at 10 again. If you remove that too then the next one to be checked against the 500 is agein at 10. So either remove it or increase the index. And as exit criteria of the loop check the index against the current amount of objects in the array.
Edit: Second part of your question: If you do your memory management right, regardless wether you ARC or not, removeObjectAtIndex should properly remove the object itself. (Unless its retain count was higher than 1 or another strong reference still exists. But even then it reduces the retain count by 1 and does exactly the right thing.)

check and remove a particular string from nsmutable array without index

In Xcode, I store some NSString in NSMutableArray.
Hello
Here
MyBook
Bible
Array
Name2
There
IamCriminal
User can enter string.
Name2
I need to delete that particular string from NSMutableArray without knowing index of the string. I have some idea that, Use iteration. Any other Best way. Plz Give with sample codings.
you can use containsObject method in an NSMutableArray
if ([yourArray containsObject:#"object"]) {
[yourArray removeObject:#"object"];
}
Swift:
if yourArray.contains("object") {
yourArray = yourArray.filter{ $0 != "object" }
}
[array removeObject:#"Name2"];
The documentation for NSMutableArray’s removeObject: method states:
matches are determined on the basis of an object’s response to the
isEqual: message
In other words, this method iterates over your array comparing the objects to #"Name2". If an object is equal to #"Name2", it is removed from the array.
[array removeObject:#"name2"];
You can try this
for(NSString *string in array)
{
if([[string lowercasestring] isEqualToSring:[yourString lowercasestring]])
{
[array removeObject:string];
break;
}
}
YOu can simply use
[yourArray removeObject:stringObjectToDelete];
This method uses indexOfObject: to locate matches and then removes them by using removeObjectAtIndex:. Thus, matches are determined on the basis of an object’s response to the isEqual: message. If the array does not contain anObject, the method has no effect.
Try this,
BOOL flag = [arrayName containsObject:Str];
if (flag == YES)
{
[arrayName removeObject:Str];
}

objective-c changing array contents inside for loop

I have an issue that (I think) might have to do with scope, but I'm not sure. I'm trying to do something that I think should be simple, but I am getting a strange result, and I could truly use some advice. I would say I'm an early-objective-c programmer, but not a complete newb.
I have written a function in objective-c that I would like to use to change the key-names in a mutable array of mutable dictionary objects. So, I want to pass in a mutable array of mutable dictionary objects, and return the same mutable array with the same dictionary objects, but with some of the key-names changed. Make sense?
I have tried several log statements in this code, which seem to indicate that everything I'm doing is working, except when the for loop is finished executing (when I try to test the values in the temp array), the array appears to contain only the LAST element in the source array, repeated [source count] times. Normally, this would lead me to believe I'm not writing the new values correctly, or not reading them correctly, or even that my NSLog statements aren't showing me what I think they are. But might this be because of scope? Does the array not retain its changes outside of the for loop?
I have put a fair amount of time into this function, and I have exhausted my bag of tricks. Can anyone help out?
-(NSMutableArray *)renameKeysIn:(NSMutableArray*)source {
/*
// Pre:
// The source array is an array of dictionary items.
// This method renames some of the keys in the dictionary elements, to make sorting easier later.
// - "source" is input, method returns a mutable array
*/
// copy of the source array
NSMutableArray *temp = [source mutableCopy];
// a temporary dictionary object:
NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];
// These arrays are the old field names and the new names
NSMutableArray *originalField = [NSMutableArray arrayWithObjects:#"text", #"created_at",nil];
NSMutableArray *replacedField = [NSMutableArray arrayWithObjects:#"title", #"pubDate", nil];
// loop through the whole array
for (int x =0; x<[temp count]; x++) {
// set the temp dictionary to current element
[dict setDictionary:[temp objectAtIndex:x]];
// loop through the number of keys (fields) we want to replace (created_at, text)... defined in the "originalField" array
for (int i=0; i<[originalField count]; i++)
{
// look through the NSDictionary item (fields in the key list)
// if a key name in the dictionary matches one of the ones to be replaced, then replace it with the new one
if ([dict objectForKey:[originalField objectAtIndex:i]] != nil) {
// add a new key/val pair: the new key *name*, and the old key *value*
[dict setObject:[dict objectForKey:[originalField objectAtIndex:i]]
forKey:[replacedField objectAtIndex:i]];
// remove the old key/value pair
[dict removeObjectForKey:[originalField objectAtIndex:i]];
}// end if dictionary item not null
}// end loop through keys (created_at, text)
[temp replaceObjectAtIndex:x withObject:dict];
}// end loop through array
// check array contents
for (int a=0; a<[temp count]; a++){
NSLog(#"Temp contents: ############ %#",[[temp objectAtIndex:a] objectForKey:#"pubDate"]);
}
return temp;
} // end METHOD
I think the issue is on the line with:
[dict setDictionary:[temp objectAtIndex:x]];
Since these things are almost all working in pointers (instead of copying contents), every element of your temp array will point to the dict dictionary, which is set to be whatever the latest key's dictionary is. I think setting the actual pointer will fix the issue.
dict = [temp objectAtIndex:x];

CLISTs in Objective C

I have cpp code where the struct objects are put into the CLISTS. I am porting this code into Objective C.
CLIST is similar to a doubly linked list with .RemoveAt , .GetAt , .InsertBefore , .GetNext , .GetHeadPosition functions.
How to implement the same in Objective C.
Do I need to implement doubly linked list in Objective C.Is there any other predefined methods to use it.
A CLIST is presumably circular? Hence the GetHeadPosition?
In any case, NSArray (or, NSMutableArray in this case, since you want to be inserting) is the normal way to keep ordered lists in Objective-C.
For RemoveAt, use removeObjectAtIndex:. For GetAt, use objectAtIndex:. For InsertBefore you're probably going to want to write a little something like:
- (void)insert:(id)objectToInsert before:(id)referenceObject
{
int index = [array indexOfObject:referenceObject];
if(index == NSNotFound) return; // or whatever you'd expect.
// Maybe object is just inserted at the end?
index = index - 1;
if(index < 0) index = [array count];
[array insertObject:objectToInsert atIndex:index];
}
(which would probably go better in an NSArray category, but you get the point)
For GetNext and GetHeadPosition you probably want to keep your array position in a separate variable. So for GetNext:
arrayPosition = (arrayPosition + 1)%[array count];
return [array objectAtIndex:arrayPosition];
And for GetHeadPosition, just:
return arrayPosition;
EDIT: for iterating through an NSArray, the easiest way is actually to ignore anything explicit and just use:
for(ObjectType *object in array)
{
/* do something with object */
}
That generally means you don't really need an analogue of GetNext, but you can't mutate the array while in that loop so it's not always usable.