Remove duplicates from NSArray of Custom Objects also compare and edit same - iphone

I have two NSMutableArrays. Each contains a custom word object in it. Custom word has 2 properties text and frequency. Now I want to combine these two arrays in such a way that, if these two arrays has same text in it, then it should compare the frequency of those two text and select the highest frequency of the two. And also it should remove the duplicates from the array.
I tried every logic for this but was not able to do this. Can any body help me with the logic for this. Following the code. But it should also remove the duplicates.
for (int i = 0; i < [array count]; i++) {
for (int j = 0; j < [array count]; j++) {
if ([[[array objectAtIndex:i]firstWord] isEqualToString:[[array objectAtIndex:j] firstWord]]) {
if ([[array objectAtIndex:i] frequency] < [[array objectAtIndex:j] frequency]) {
CustomWordFrequency *word = [array objectAtIndex:i];
word.frequency = [[array objectAtIndex:j] frequency];
[array replaceObjectAtIndex:i withObject:word];
}
}
}
}

Combine the two arrays.
Sort the resulting array by text ASC, frequency DESC
Loop through the array
a. Look at the next item in the array. If the text is the same as the current word, remove it from the array. If it's different, continue looping.
NSArray *combined = [firstArray arrayByAddingObjectsFromArray:secondArray];
[combined sortUsingComparator:^(id firstObject, id secondObject) {
NSComparisonResult *result = [firstObject.text compare:secondObject.text];
if (result == NSOrderedAscending) return NSOrderedAscending;
if (result == NSOrderedDescending) return NSOrderedDescending;
if (result == NSOrderedSame) {
result = [firstObject.frequency compare:secondObject.frequency];
if (result == NSOrderedAscending) return NSOrderedDescending;
if (result == NSOrderedDescending) return NSOrderedAscending;
if (result == NSOrderedSame) return NSOrderedSame;
}
}];
for (int i = 0; i < [combined count] - 2; ++i) {
CustomWordFrequency *word = [combined objectAtIndex:i];
int j = i + 1;
while ([word.text compare:[combined objectAtIndex:j].text == NSOrderedSame) {
[combined removeObjectAtIndex:j];
j++;
if (j == [combined count]) {break;}
}
if (i >= [combined count] - 2) {break;} // the count keeps changing so check here
}

NSMutableArray *combinedArray = [[NSMutableArray alloc] init];
BOOL flagForMatchFound = FALSE;
for(CustomWordFrequency *firstWord in firstArray)
{
flagForMatchFound = FALSE;
for(CustomWordFrequency *secondWord in secondArray)
{
if([firstWord.firstWord isEqualToString:secondWord.firstWord])
{
if(firstWord.frequency >= secondWord.frequency)
{
[combinedArray addObject:firstWord];
flagForMatchFound = TRUE;
}
else
[combinedArray addObject:secondWord];
}
else
{
if(!flagForMatchFound)
[combinedArray addObject:secondWord];
}
}
}

Related

Sort NSArray for a specific order

I have an NSArray of custom objects.
Each object contains one integer value for ex. 1,2,3,4
Now I want to sort Array like below
9 7 5 3 1 2 4 6 8
Could some one help me?
Here is your answer.
Hope your first array is in sorted order (ascending) if not then you need to sort it first.
NSMutableArray *myArray = [NSMutableArray array];
//Populate your array with custom objects. I had created my own which contain an integer type property.
[myArray addObject:[[myObject alloc] initWithId:11 objectName:#"K"]];
[myArray addObject:[[myObject alloc] initWithId:3 objectName:#"C"]];
[myArray addObject:[[myObject alloc] initWithId:4 objectName:#"D"]];
....
...
.... and so on
then sort it in Ascending order. You can do it Descending also but then you need to change the below logic little bit. I showing with Ascending order.
NSArray *tempArray = [myArray sortedArrayUsingComparator:^NSComparisonResult(myObject *obj1, myObject *obj2) {
if([obj1 objectId] > [obj2 objectId]) return NSOrderedDescending;
else if([obj1 objectId] < [obj2 objectId]) return NSOrderedAscending;
else return NSOrderedSame;
}];
Now sort them as per your requirement
NSMutableArray *finalArray = [NSMutableArray arrayWithArray:tempArray];
NSInteger totalObjects = [tempArray count];
NSInteger centerObjectIndex = totalObjects>>1;
__block NSInteger rightPosition = centerObjectIndex + 1;
__block NSInteger leftPosition = centerObjectIndex - 1;
__block BOOL toggle = NO;
[tempArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if(idx == 0) [finalArray replaceObjectAtIndex:centerObjectIndex withObject:obj];
else
{
if(toggle)
{
if(leftPosition >= 0)
{
[finalArray replaceObjectAtIndex:leftPosition withObject:obj];
leftPosition -= 1;
}
}
else
{
if(rightPosition < totalObjects)
{
[finalArray replaceObjectAtIndex:rightPosition withObject:obj];
rightPosition += 1;
}
}
toggle = !toggle;
}
}];
Here is the final step if your array contains an even numbers of objects
if(!(totalObjects % 2))
{
[finalArray removeObjectAtIndex:0];
[finalArray addObject:[tempArray objectAtIndex:totalObjects-1]];
}
Now you are at end. Your array named finalArray get sorted as per your requirement.

Remove certain objects from NSMutableArray [duplicate]

This question already has answers here:
Removing object from NSMutableArray
(5 answers)
Closed 9 years ago.
I have an NSMutableArray of objects which are of AdDetail class that hold a few properties (for eg. adId, adTitle, adPrice... etc). I want to remove only those objects which have adID = 0. How can I do that ?
Perhaps something more elegant would suffice?
[array removeObjectsInArray:[array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"adID == 0"]]];
Using predicate
NSArray *filtered=[array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(adId == 0)"]];
Using fastEnumeration:
NSMutableArray *newArray=[NSMutableArray new];
for(AdDetail adDetailObj in array){
if(![[adDetailObj adId] isEqualToString:#"0"]){ //if these are strings, if NSInteger then directly compare using ==
newArray[newArray.count]=adDetailObj;
}
}
Now newArray contains all objects other than id=0
Use following code :
int count = array.count;
for(i=0;i<count;i++){
ADetail *adetail = [array objectAtIndex:i];
if(adetail.adID = 0){
[array removeObjectAtIndex:i];
i--;
}
count = array.count;
}
NSMutableArray *newArray = [NSMutableArray arrayWithArray:yourArray];
for (int i = 0; i < yourArray.count; i++)
{
AdDetail *obj = (AdDetail *)[yourArray objectAtIndex:i];
if (obj.adID == 0)
[newArray removeObjectAtIndex:i];
}
yourArray = [newArray mutableCopy];
for(i=0; i < myArray.count; i++)
{
myClass = [myArray objectAtIndex:i];
if([myClass.adID isEqualtoString:"0"])// if it it int/NSInteger the write myClass.adID==0
{
[myArray removeObjectAtIndex:i];
i--;
}
}
predicate = #"adID == 0";
newArray = [theArray filterUsingPredicate:aPredicate]

How to check the last array element and change the button image

How to get check change the button image if it reach the last element of the array and perform to start from first on click that button?
Here my code,Please help me
-(IBAction)changenext:(id)sender
{
static int j = 0;
backimg.enabled=TRUE;
if(sender == nextimg)
j++;
else if(sender == backimg)
j--;
if (j >= arcount)
{
j = 0;
}
else if(j < 0)
{
j = arcount - 1;
}
imager.image=[arimage objectAtIndex:j];
}
What change should i made?
Hi i can not clearly understand what you asking but simply you get last element of NSArray with this code :-
[myArray lastObject]
For Example:-
NSString *str = [myArray lastObject]

How to compare elements in int array to a integer?

I want to compare an array containing int values to a number
example [1,2,30,1,40,200,10,500] < 500 meaning if array contains elements less than 500.
How can i do dis?
Thank alot in advance
I did this bt it say invalid opernd:
if ([placeName count])
{
for (int i =0; i < [placeName count]; i++)
{
NSArray *sortedArray=[placeName sortedArrayUsingFunction:intSort context:NULL];
self.placeName = [NSMutableArray arrayWithArray:sortedArray];
NSMutableArray *tempArray = [sortedArray objectAtIndex:i];
NSDecimalNumber *Distance = [tempArray objectForKey:#"distance"];
NSMutableArray *intDistanse=[Distance intValue];
DLog(#"Distance%d", intDistanse);
NSMutableArray *intDistanse=[Distance intValue];
DLog(#"Distance%d", intDistanse);
for(int j = 0; j < [intDistanse count]; j++)
{
if ( intDistanse[j] < 500 ) //here its says error
{
DLog(#"success");
}
}
}
}
What kind of an array? NSArray or language array?
Easiest way is a loop. Without knowing the type of the array, this is pseudo code.
for(int i = 0; i < arrayCount; i++)
if ( array[i] < 500 )
.... got an element less than 500 ....
The code doesn't really make sense:
that code should be generating a ton of compiler warnings; every warning indicates a bug that should be fixed. Also, try "Build and Analyze".
you are sorting an array every time through the loop; waste of resources and doesn't make sense
everything being typed as NSMutableArray* doesn't make sense; do you really have an array of arrays of arrays?
... calling objectForKey: on anything but an NSDictionary doesn't work
intValue returns an (int), not an NSMutableArray*
if intDistance is an (int), then it should just be ( intDistance < 500 )
Overall, I would suggest you step back and review the Objective-C language guide and a bunch of working examples.
Typically, you loop over each element in the array, checking if each element is less than 500.
For example:
int i;
for (i=0; i < THE_SIZE_OF_THE_ARRAY; ++i)
{
if (array[i] < 500)
{
/* Do something */
}
}
If you want to see whether there is at least one item that matches your condition:
bool found = false;
for(int i = 0; i < sizeof(example)/sizeof(example[0]); ++i)
{
if(example[i] < 500)
{
found = true;
break;
}
}
And if you want to check whether all items match your condition:
bool found = true;
for(int i = 0; i < sizeof(example)/sizeof(example[0]); ++i)
{
if(example[i] >= 500)
{
found = false;
break;
}
}
Did find a solution to it type casting:
NSMutableArray *tempArray = [sortedArray objectAtIndex:i];
//DLog(#"sortedArray%#", sortedArray);8=
NSNumber *DistanceNum = [tempArray objectForKey:#"distance"];
NSLog(#"distance%#:::",DistanceNum);
NSInteger intDistance = (int)[DistanceNum floatValue];
if(intDistance<500)
{
NSLog(#"h:)");
NSString *notifications =#"Yes";
[[AppHelper mDataManager] setObject:notifications forKey:#"notifications"];
NSLog(#"notifications:%#",notifications);
RemindMeViewController *object = [[RemindMeViewController alloc] initWithNibName:#"RemindMeViewController" bundle:nil];
// RemindMeViewController *object=[[RemindMeViewController alloc]initWithNibName];
NSLog(#"notifications set");
[object scheduleNotification];
}
You can do this very easily by just implementing the observer to compare. Following is just an example to implement the custom observer to compare
#implementation NSArray (KVO)
- (void)addObserver:(NSObject *)observer toObjectsAtIndexes:(NSIndexSet *)indexes forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
{
NSUInteger idx=[indexes firstIndex];
while(idx!=NSNotFound)
{
[[self objectAtIndex:idx] addObserver:observer
forKeyPath:keyPath
options:options
context:context];
idx=[indexes indexGreaterThanIndex:idx];
}
}
- (void)removeObserver:(NSObject *)observer fromObjectsAtIndexes:(NSIndexSet *)indexes forKeyPath:(NSString *)keyPath
{
NSUInteger idx=[indexes firstIndex];
while(idx!=NSNotFound)
{
[[self objectAtIndex:idx] removeObserver:observer
forKeyPath:keyPath];
idx=[indexes indexGreaterThanIndex:idx];
}
}
-(void)addObserver:(id)observer forKeyPath:(NSString*)keyPath options:(NSKeyValueObservingOptions)options context:(void*)context;
{
if([isa instanceMethodForSelector:_cmd]==[NSArray instanceMethodForSelector:_cmd])
NSRaiseException(NSInvalidArgumentException,self,_cmd,#"not supported for key path %# (observer was %#)", keyPath, observer);
else
[super addObserver:observer
forKeyPath:keyPath
options:options
context:context];
}
-(void)removeObserver:(id)observer forKeyPath:(NSString*)keyPath;
{
if([isa instanceMethodForSelector:_cmd]==[NSArray instanceMethodForSelector:_cmd])
NSRaiseException(NSInvalidArgumentException,self,_cmd,#"not supported for key path %# (observer was %#)", keyPath, observer);
else
[super removeObserver:observer
forKeyPath:keyPath];
}
#end

Transform a "for...in...break" loop into a "while" loop

Can I transform this loop in a while loop ?
int i=0;
for (NSDictionnary *crossArrayDictionnary in (NSArray *)mainArray) {
//some code...
i++;
if (i>=50) {
break;
}
}
Thanks,
This should do the trick:
NSInteger max, i = 0;
max = [mainArray count] < 50 ? [mainArray count] : 50;
while (i < max) {
NSDictionary *crossArrayDictionnary = [mainArray objectAtIndex:i];
// You code here.
i++;
}
NSEnumerator *enumerator = [mainArray objectEnumerator];
NSDictionary *crossArrayDictionnary = nil;
while ((crossArrayDictionnary = [enumerator nextObject])) {
//some code...
i++;
if (i>=50) {
break;
}
}
As rckoenes said,
Minor change.
NSInteger i = 0;
while (i < 50 && [itemsMutable cout] >= i) {
NSDictionary *crossArrayDictionnary = [itemsMutable objectAtIndex:i];
// You code here.
i++;
}
don't know objective-c, but something like this:
int i=0;
while (i < 50 && i < [mainArray count]) {
NSDictionary *crossArrayDictionnary = [mainArray objectAtIndex:i];
//some code...
i++;
}