Comparing NSMutableArray Elements for Values - objective-c

I am looking for a way to compare the contents of two NSMutableArray objects. Both arrays are filled with NSMutableDictionaries which were allocated separately but occasionally contain the same data.
Simplified Example:
NSMutableArray *firstArray = [[NSMutableArray alloc] init];
NSMutableArray *secondArray = [[NSMutableArray alloc] init];
NSMutableDictionary *a = [[NSDictionary alloc] init];
[a setObject:#"foo" forKey:"name"];
[a setObject:[NSNumber numberWithInt:1] forKey:"number"];
NSMutableDictionary *b = [[NSDictionary alloc] init];
[b setObject:#"bar" forKey:"name"];
[b setObject:[NSNumber numberWithInt:2] forKey:"number"];
NSMutableDictionary *c = [[NSDictionary alloc] init];
[c setObject:#"foo" forKey:"name"];
[c setObject:[NSNumber numberWithInt:1] forKey:"number"];
[firstArray addObject:a];
[firstArray addObject:b];
[secondArray addObject:c];
a, b and c are distinct object, but the contents of a and c match.
What I am looking for is a function / approach to compare firstArray and secondArray and return only b.
In Pseudocode:
NSArray *difference = [self magicFunctionWithArray:firstArray andArray:secondArray];
NSLog(#"%#",difference)
=> ({name="bar"; number=2})
Thank you in advance.

This can be achieved using NSMutableSet instances.
NSMutableSet * firstSet = [NSMutableSet setWithArray:firstArray];
NSMutableSet * secondSet = [NSMutableSet setWithArray:firstArray];
[firstSet unionSet:[NSSet setWithArray:secondArray]];
[secondSet intersectSet:[NSSet setWithArray:secondArray]];
[firstSet minusSet:secondSet];
NSLog(#"%#", firstSet);

Related

Converting NSMutableSet to NSSet

Is there a way to convert NSMutableSet to NSSet? I have tried several methods: moving to an NSArray and the setWithArray; instantiating an NSSet with the contents of the NSMutableSet. The program compiles but I get a run time error.
NSMutableArray *temp = [[NSMutableArray alloc] init];
NSMutableSet *num1 = [[NSMutableSet alloc] init];
NSArray *num2 = [[NSArray alloc] init];
NSSet *num3 = [[NSSet alloc] init];
num1 = [checkset mutableCopy]; //checkset is of type NSSet
num2 = [NSArray arrayWithArray:NoShows];
num3 = [NSSet setWithArray:num2];
[num1 minusSet:num3];
copy of NSMutableSet returns a NSSet
In your sample:
NSSet *immutableSet = [checksetM copy]; // returns immutable copy
-(NSSet *)ContainsNoShow:(NSMutableArray *)checkset
{
NSSet *newcheckset = [[NSSet alloc] init];
newcheckset = [NSSet setWithArray:NoShows];
NSMutableSet *checksetM = [NSMutableSet setWithArray:checkset];
[checksetM minusSet: newcheckset];
return checksetM;
}

Add multiple objects to an array [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
just getting back into coding after a long break, and picking up Objective C.
I want to add multiple objects to an array. I can do it explicitly (as below) but I'm sure there must a smarter, iterative way to do it.
NSMutableArray *a =[NSMutableArray array];
Class A *c1 = [[Class A alloc]init];
[c1 setVAlueX:5];
[c1 setValueY:3];
[a addobject:c1];
Class A *c2 = [[Class A alloc]init];
[c2 setVAlueX:5];
[c2 setValueY:3];
[a addobject:c2];
Class A *c3 = [[Class A alloc]init];
[c3 setVAlueX:5];
[c3 setValueY:3];
[a addobject:c3];
etc
This is nice and short:
NSArray *a = #[[A aWithX:5 Y:3], [A aWithX:5 Y:3], [A aWithX:5 Y:3]];
You'll have to implement a convenience constructor in class A:
+ (instancetype)aWithX:(int)x Y:(int)y
{
A *a = [[self alloc] init];
[a setValueX:x];
[a setValueY:y];
}
Try this
NSMutableArray *a =[[NSMutableArray alloc] init];
NSMutableArray *b =[[NSMutableArray alloc] init];
NSMutableArray *c =[[NSMutableArray alloc] init];
NSMutableDictionary *dictA = [[NSMutableDictionary alloc] init];
NSMutableDictionary *dictB = [[NSMutableDictionary alloc] init];
NSMutableDictionary *dictC = [[NSMutableDictionary alloc] init];
Class A *c1 = [[Class A alloc]init];
[dictA setObject:[NSString stringWithFormat:#"5"] forKey:#"ID1"];
[dictA setObject:[NSString stringWithFormat:#"3"] forKey:#"ID1"];
//[c1 setVAlueX:5];
//[c1 setValueY:3];
[a addobject: dictA];
Class A *c2 = [[Class A alloc]init];
[dictB setObject:[NSString stringWithFormat:#"5"] forKey:#"ID1"];
[dictB setObject:[NSString stringWithFormat:#"3"] forKey:#"ID1"];
//[c2 setVAlueX:5];
//[c2 setValueY:3];
[a addobject: dictB];
Class A *c3 = [[Class A alloc]init];
[dictC setObject:[NSString stringWithFormat:#"5"] forKey:#"ID1"];
[dictC setObject:[NSString stringWithFormat:#"3"] forKey:#"ID1"];
//[c3 setVAlueX:5];
//[c3 setValueY:3];
[a addobject: dictC];

NSMutableArray EXEC_BAD_ACCESS on initWithObjects

Is the following legal in Objective-c with ARC enabled?
NSMutableArray * smallArray = [[NSMutableArray alloc] initWithObjects:#"1", #"2", #"3", nil];
smallArray = [[NSMutableArray alloc] initWithObjects:#"4", "5", nil];
I thought it should be. However, in this situation it gives me EXEC_BAD_ACCESS on the forth line:
NSMutableArray * bigArray = [[NSMutableArray alloc] init];
NSMutableArray * smallArray = [[NSMutableArray alloc] initWithObjects:#"1", #"2", #"3", nil];
[bigArray addObject: smallArray];
smallArray = [[NSMutableArray alloc] initWithObjects:#"4", "5", nil];
addObject copies the pointer right? So if I allocate a new segment of memory to smallArray to point to, what is wrong with that?
However this code segment does not crash:
NSMutableArray * bigArray = [[NSMutableArray alloc] init];
NSMutableArray * smallArray = [[NSMutableArray alloc] initWithObjects:#"1", #"2", #"3", nil];
[bigArray addObject: smallArray];
smallArray = [[NSMutableArray alloc] init];
[smallArray addObject:#"4"];
[smallArray addObject:#"5"];
What's going on here?
Try this:
smallArray = [[NSMutableArray alloc] initWithObjects:#"4", "5", nil];
The second object must be #"5", not just "5".
I guess this is because you forgot the # in the string "5". it should be:
smallArray = [[NSMutableArray alloc] initWithObjects:#"4", #"5", nil];

Objective C How to fill rangeOfString of a NSArray?

I wonder if it is possible to fill rangeOfString objects of a NSArray. Because I have a long list of objects for after rangeOfString:
NSArray biglist´s count is higher than list´s count.
I want to filter away the objects from the small list of the main list.
Please tell me if this is not clear.
My codes below:
NSArray *biglist = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"mainlist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSArray *list = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"smalllist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
for (NSString *listword in list);
NSMutableArray *wordlist = [[NSMutableArray alloc] init];
NSMutableArray *worindex = [[NSMutableArray alloc] init];
NSMutableIndexSet *mindexes = [[NSMutableIndexSet alloc] init];
NSMutableDictionary *mutdic = [[NSMutableDictionary alloc] init];
NSMutableArray *mutarray = [[NSMutableArray alloc] init];
for (NSString *s in mainlist)
{
NSRange ran = [s rangeOfString:listword];
if (ran.location !=NSNotFound)
{
//my codes here
}
}
EDIT:
I think I can solve this by writing
int i;
for (i = 0; i<[list count]; i++)
{
NSString *same = [list objectAtIndex:i];
NSLog (#"listword: %#", same);
}
But I am not sure where to place it, inside the for loop s in mainlist or outside.
EDIT: This for loop works inside the main for loop.
EDIT:
Tried these codes, but it doesnt work somehow..
NSArray *list = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"small" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSArray *mainlist = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"mainlist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSMutableArray *large = [NSMutableArray arrayWithArray:mainlist];
NSArray *newlarge;
for (NSString *listword in list)
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(SELF beginswith[c] %#)",listword];
newlarge = [large filteredArrayUsingPredicate:predicate];
}
NSLog (#"large: %#", newlarge);
NSLog (#"finished!");
"I want to filter away the objects from the small list of the main list."
If I understand correctly, you want to remove an array of items from another array. You don't want to do that much work and allocations inside an n^2 loop.
This removes an array of items from another array. Depending on how large your array is you may need to optimize further but this works:
NSArray *small = [NSArray arrayWithObjects:#"three", #"two", nil];
NSMutableArray *large = [NSMutableArray arrayWithObjects:#"one", #"two", #"three", #"four", nil];
[large removeObjectsInArray:small];
// print
for (NSString *current in large)
{
NSLog(#"item: %#", current);
}
This outputs:
2011-10-13 08:39:21.176 Craplet[5235:707] item: one
2011-10-13 08:39:21.178 Craplet[5235:707] item: four
I figured it out by myself and solved this :)
It works almost perfectly.
My codes:
NSArray *big = [[NSArray alloc] initWithObjects:#"hello ->mache", #"heisann hoppsann ->hiya", #"nei men ->da", #"however ->what", #"may ->april", #"mai ->maj", nil];
NSArray *small = [[NSArray alloc] initWithObjects: #"heisann ", #"nei men ", #"however ", #"mai", nil];
NSMutableArray *smallwithh = [[NSMutableArray alloc] init];
NSMutableIndexSet *mindexes = [[NSMutableIndexSet alloc] init];
for (NSString *same in small)
{
NSLog (#"listword: %#", same);
for (NSString *s in big)
{
NSRange ran = [s rangeOfString:same];
if (ran.location !=NSNotFound)
{
[smallwithh addObject:s];
NSUInteger ind = [big indexOfObject:s];
[mindexes addIndex:ind];
}
}
}
NSLog (#"smallwith: %#", smallwithh);
[smallwithh release];
NSMutableArray *newWords =[NSMutableArray arrayWithArray: big];
[newWords removeObjectsAtIndexes: mindexes];
[big release];
[small release];
NSLog (#"newWords: %#", newWords);

How to copy last object of array to other array?

how would you copy the last object of a array and then add the object to some array. So in other words i want to take the last object of someArray and copy that lastObject to someArray2.
Thanks,
-David
NSArray *firstArray = [[NSArray alloc] init];
... populate firstArray ...
NSArray *secondArray = [NSArray arrayWithObject:[firstArray lastObject]];
or
NSArray *firstArray = [[NSArray alloc] init];
... populate firstArray ...
NSMutableArray *secondArray = [NSMutableArray alloc] init];
[secondArray addObject:[firstArray lastObject]];
or
NSArray *firstArray = [[NSArray alloc] init];
... populate firstArray ...
NSArray *secondArray = [[NSArray alloc] init];
NSArray *thirdArray = [secondArray arrayByAddingObject:[firstArray lastObject]];
Make sure everything is released as you now own all these references.
Edit: If you want a COPY everywhere there's [firstArray lastObject] change it to [[[firstArray lastObject] copy] autorelease] (thanks tc)