Trying to add many arrays to one NSMutableArray - iphone

I'm Trying here to add many arrays to one NSMutableArray
Actually am adding the same array with different values Many Times to one NSMutable Array
this the code:
NSMutableArray* wordsArray =[[NSMutableArray alloc] init ];
NSMutableArray* meaningsArray=[[NSMutableArray alloc]init];
NSMutableArray* wordsArrayTemp=[[NSMutableArray alloc]init];
NSMutableArray* meaningsArrayTemp=[[NSMutableArray alloc]init ];
NSMutableArray* allWords =[[NSMutableArray alloc]initWithCapacity:2];
NSMutableArray* allMeanings=[[NSMutableArray alloc]initWithCapacity:2];
for(int i=0;i<2;i++)
{
int wordsCounter=0;
[wordsArrayTemp removeAllObjects];
[meaningsArrayTemp removeAllObjects];
for(NSString *tmp in wordsArray)
{
NSString *meaning =[meaningsArray objectAtIndex:wordsCounter++];
subtmp= [ tmp substringWithRange:NSMakeRange(0,1)];
if([currentTable isEqualToString:#"arabicToEnglish"])
{
if([subtmp isEqualToString:[arabicLetters objectAtIndex:i]])
{
[wordsArrayTemp addObject:tmp];
[meaningsArrayTemp addObject:meaning];
}
}
else
if([subtmp isEqualToString:[englishLetters objectAtIndex:i]])
{
[wordsArrayTemp addObject:tmp];
[meaningsArrayTemp addObject:meaning];
}
}
[allWords insertObject:wordsArrayTemp atIndex:i];
// [allWords addObject: wordsArrayTemp];
[allMeanings addObject:meaningsArrayTemp];
NSLog(#"all words count%i",[[allWords objectAtIndex:i] count]);
}
The Problem :
The supposed behavior here is to have 2 different values in the allWords array .
But what Actually happens is that the 2 values filled with the same value with the last index Value.
I mean [allWords objectAtIndex:0] should have 2000 object and [allWords objectAtIndex:1] should have 3000 ,but what happens that they both have 3000 object !!
what am I missing here?!!
thnx

when you add an object to an array the object is not copied. You just save its memory address.
Basically you added the same temporary array to the parent array. And you did all your array manipulations to the same array.
Maybe this piece of unrolled loop code will make it a little bit clearer.
// create new array on a specific memory address. let's say this address is 0x01
NSMutableArray* wordsArrayTemp=[[NSMutableArray alloc]init];
// first iteration of your loop
// remove all objects from array at memory address 0x01
[wordsArrayTemp removeAllObjects];
// add objects to the array at address 0x01
[wordsArrayTemp addObject:tmp];
// insert array (still at address 0x01) to the parent array
[allWords insertObject:wordsArrayTemp atIndex:i];
// your allWords array now looks like this: {array#0x01}
// second iteration of your loop
// remove all objects from array at memory address 0x01!!! (still the same array as in the first iteration)
// since it's the same array all objects from the array at [allWords objectAtIndex:0] are removed too
[wordsArrayTemp removeAllObjects];
// add objects to the array at address 0x01
[wordsArrayTemp addObject:tmp];
// insert array (still at address 0x01) to the parent array
[allWords insertObject:wordsArrayTemp atIndex:i];
// your allWords array now looks like this {array#0x01, array#0x01}
the solution is pretty easy.
At the beginning of the for-loop instead of removing allObjects from the array create new arrays.
Just replace
[wordsArrayTemp removeAllObjects];
[meaningsArrayTemp removeAllObjects];
with
wordsArrayTemp = [NSMutableArray array];
meaningsArrayTemp = [NSMutableArray array];

Try to add one array simutaneously :
[[allWords array] addObject:wordsArray.array];
Hope it'll help

Try this:-
[allWords insertObject:[wordsArrayTemp copy] atIndex:i];
It should work.

Related

NSMutableArray replace object

I try to find object in my array and if success I need to replace object from my array to new object
for (id existingSig in allSignature)
if ([[existingSig objectForKey:#"SignatureName"] isEqualToString:[item objectForKey:#"name"]])
{
[allSignature removeObject:existingSig];
[allSignature addObject:[NSDictionary dictionaryWithObjectsAndKeys:#"1", #"SignatureIsRich", [item objectForKey:#"name"], #"SignatureName", generatedID, #"SignatureUniqueId", nil]];
}
I have error 'NSCFArray: 0x100551f10> was mutated while being enumerated'
As others have said, you cannot mutate a MutableArray while it is being Enumerated. You could handle it by having two arrays of what to remove and what to add after the loop.
NSMutableArray *remove = [NSMutableArray array];
NSMutableArray *add = [NSMutableArray array];
for (id existingSig in allSignature){
if ([[existingSig objectForKey:#"SignatureName"] isEqualToString:[item objectForKey:#"name"]])
{
// Add to the array of objects to be removed
[remove addObject:existingSig];
// Add to the array of objects to be added
[add addObject:[NSDictionary dictionaryWithObjectsAndKeys:#"1", #"SignatureIsRich", [item objectForKey:#"name"], #"SignatureName", generatedID, #"SignatureUniqueId", nil]];
}
}
[allSignature removeObjectsInArray:remove]; // Remove objects
[allSignature addObjectsFromArray:add]; // Add new objects
The easiest way is to make a copy and iterate over that, then modify the original.
I have a map array method I have in a NSArray Category for this very purpose
- (NSArray *) cw_mapArray:(id (^)(id obj))block
{
NSMutableArray * cwArray = [[NSMutableArray alloc] init];
[self cw_each:^(id obj, NSUInteger index, BOOL *stop) {
id rObj = block(obj);
if (rObj) {
[cwArray addObject:rObj];
}
}];
return cwArray;
}
this way I can get a new array and then just change the array with the new array. You can change cw_each to enumerateObjectsUsingBlock:. Basically this is simple, if you want to map the object to the new array you just return the object as is in the block, otherwise modify it and return that or if you don't want to map the object to the new array then return nil. Its not very much code and works wonderfully.

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.

adding Array variables into a list of array

I am having three array variables from different array list , how to add them and place them in a single array list.i.e suppose if abc is from array list 1,pqr from array list2 and xyz from array list3 , after adding into new list arraylist 4 should have abc,pqr,xyz
If I understand your question correctly, just do:
NSMutableArray *newArray = [NSMutableArray array];
[newArray addObjectsFromArray:array1];
[newArray addObjectsFromArray:array2];
[newArray addObjectsFromArray:array3];
Use the below method of NSMutableArray.
- (void)addObjectsFromArray:(NSArray *)otherArray
otherArray : An array of objects to add to the end of the receiving array’s content.
See in Apple Documentation.
I assume list1,list2,list3 is either the type of NSArray OR NSMutableArray.
NSMutableArray *myArray = [NSMutableArray alloc] init];
[myArray addObjectsFromArray:list1];
[myArray addObjectsFromArray:list2];
[myArray addObjectsFromArray:list3];

how can I save NSMutableArray into NSMutableArray so that previous data in NSMutableArray remain same?

I want to know that how can I add NSMutableArray in to an NSMutableArray so that previous data should not lost, and new data will be added on next indexes.
If you don't understand it then you can ask again to me,
I will appraise the right answer.
my code is as below
-(void)setArray1:(NSMutableArray *)arrayValueFromNew
{
self.myArray=arrayValueFromNew;
myArray2 = [[NSMutableArray alloc] initWithArray:arrayValueFromNew];
for(int i=0;i<[myArray2 count];i++)
{
[myArray addObject:[myArray2 objectAtIndex:i]];
}
}
In your code, myArray and myArray2, both have same objects as you are assigning the arrayValueFromNew array to both. So it kind of doesn't make sense.
But to answer your question 'how to add one array to another?' do :
[mutableArray1
addObjectsFromArray:array2];
EDIT:
this is how your method should look
-(void)setArray1:(NSMutableArray *)arrayValueFromNew
{
if(!self.myArray)
{
self.myArray = arrayValueFromNew;
}
else
{
[self.myArray addObjectsFromArray:arrayValueFromNew];
}
}
Your 'myArray must be initialized. You can initialize it in viewDidLoad or init:
self.myArray = [[NSMutableArray alloc]
initWithCapacity:1];
NSMutableArray *array1 = [NSMutableArray array], *array2 = [NSMutableArray array];
// add some objects to the arrays
[array1 addObjectsFromArray:array2];
//array1 now contains all the objects originally in array1 and array2
This will work,
NSMutableArray *mutarr=[[NSMutableArray alloc]initWithArray: array1]
It looks like you just want a new copy of the old array. There is a handy function for that
NSMutableArray *newArray = [oldArray mutableCopy];
Remember that you've used copy in getting this array so you are responsible for managing the memory of newArray
EDIT
What is your code doing?
-(void)setArray1:(NSMutableArray *)arrayValueFromNew //1
{
self.myArray=arrayValueFromNew; //2
myArray2 = [[NSMutableArray alloc] initWithArray:arrayValueFromNew]; //3
for(int i=0;i<[myArray2 count];i++)
{
[myArray addObject:[myArray2 objectAtIndex:i]]; //4
}
}
This looks like a setter for a property array1
You are setting the property 'array' to arrayValueFromNew. Since I don't know whether this property has been declared with retain or copy I don't know whether array is a pointer to arrayValueFromNew or a pointer to a copy of arrayValueFromNew
You set myArray2 to be a new array that contains the objects of arrayValueFromNew
For each object in myArray2 (which are the objects from arrayValueFromNew. see point 3) you add this object to myArray. Assuming myArray is an NSMutableArray it started with the objects from arrayValueFromNew which you have now added again. It contains each item in arrayValueFromNew twice.

how to add the element in the array using the for loop in objective-c?

is this the right way to do the same?
nsmutablearray *myarray1 //have some data in it
for (int i=0;i< [myarray1 count]; i++)
{
myArray2 = [NSMutableArray array];
[myArray2 addObject:i];
}
and how can i print this value of myarray2.
If you are trying to copy element of one array to other array then use following code:
NSMutableArray *secondArray = [NSMutableArray arrayWithArray:firstArray];
If you want to print element value then depending upon data stored in your array you can print element.
i.e if array contains string object then you can print like this:
for(int i=0;i<secondArray.count;i++)
{
NSLog(#"Element Value : %#",[secondArray objectAtIndex:i]);
}
if array contains any user define object then you can print like this:
for(int i=0;i<secondArray.count;i++)
{
UserDefineObject *obj = [secondArray objectAtIndex:i];
NSLog(#"Element Value with property value: %#",obj.property);
}
The easiest way to create a new array containing the same elements as the old array is to use NSCopying or NSMutableCopying.
NSArray* myArray2 = [myArray1 copy]; // myArray2 is an immutable array
NSMutableArray* myArray3 = [myArray1 mutableCopy]; // myArray3 is an mutable array
If you want to print the contents of an array for debugging purposes:
NSLog(#"myArray2 = %#", myArray2);
If you want prettier printing for a UI, you'll need to iterate through as others have suggested.