Compare two items in one NSArray - objective-c

I have an array containing twenty items. I want to search through the array, comparing one item to the next one in the array, and then print the larger item. I have already sorted the array. I just want to compare the two items, check what the remainder is between the two values, and if it's greater than say, four, print the larger item.

NSArray* arr = [NSArray arrayWithObjects:
[NSNumber numberWithInt:1],
[NSNumber numberWithInt:6],
[NSNumber numberWithInt:7],
[NSNumber numberWithInt:11],
nil
];
int len = [arr count];
for (int i=0; i < len-1; ++i) {
int num1 = [[arr objectAtIndex:i] intValue];
int num2 = [[arr objectAtIndex:i+1] intValue];
if ( num2-num1 > 4 ) {
NSLog(#"%d", num2);
}
}
--output:--
6

NSEnumerator *itemEnumerator = [theArray objectEnumerator];
YourClass *lastObject = [itemEnumerator nextObject];
YourClass *compareObject;
while( (compareObject = [itemEnumerator nextObject]) != nil)
{
if( /* place your condition here */ )
{
NSLog( … );
}
lastObject = compareObject;
}
Typped in Safari

Related

Compare NSArray elements to NSNumber

I'm new to objective c. I am getting my data from an NSArray and want to return value according to some condition. My code is:
NSArray *myData;
NSNumber *day = 5;
myData = [NSArray arrayWithObjects: #"5", nil];
for (int i = 0; i < [myData count]; i++) {
if(day == myData[0]){
NSLog(#"date in valueForDay %# ", da );
return 3;
}
}
Above code doesn't execute my statements (NSLog and return one).
But if i statically compare day with any number it got executed. Like:
NSArray *myData;
NSNumber *day = 5;
myData = [NSArray arrayWithObjects: #"5", nil];
for (int i = 0; i < [myData count]; i++) {
if(day == 5){
NSLog(#"date in valueForDay %# ", da );
return 3;
}
}
can anyone please tell me where i'm doing wrong?
You have created array with string value not with number value. That's why object from your array is "5" which is not equal to integer 5. Make your array as number array.
myData = [NSArray arrayWithObjects: #5, nil];
Also instead of for loop you can simply use indexOfObject to check array having object or not.
NSInteger index = [myData indexOfObject: day];
if(index != NSNotFound) {
return 3;
}
You stored NSString in NSArray. And comparing with NSNumber. You have to add one line above if condition and change your condition.
NSString *myString = [day stringValue];
if([myString isEqualToString:myData[0]])

How to multiply respective objects of NSArray and get the sum?

I have one array with data A=[a,b,c] and another with data B=[d,e,f]. I need to perform this type of operation a.d+ b.e+c.f (Note=Here (.) denotes multplication)and get the result. How can i do that using Objective-C?
Thanks in advance.
Define the function that does the multiplication and addition like this:
- (double)multiply:(NSArray <NSNumber *> *)vector1 withVector:(NSArray <NSNumber *> *)vector2 {
NSAssert(vector1.count == vector2.count, #"Both arrays should contain the same number of elements");
__block double result = 0;
[vector1 enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
double first = obj.doubleValue;
double second = vector2[idx].doubleValue;
result += first * second;
}];
return result;
}
This uses a block enumeration method on NSArray which gives me in index and a value, which I can use to get the value at the same index in the second array. Note also that I am using a typed array, so I don't have to cast the values to NSNumbers when using them.
Now you can just use the function:
NSArray *a = #[#1, #2, #3];
NSArray *b = #[#4, #5, #6];
NSArray *c = #[#1, #1, #1];
double res1 = [self multiply:a withVector:b]; // => 32.000000
double res2 = [self multiply:b withVector:c]; // => 15.000000
double res3 = [self multiply:c withVector:a]; // => 6.000000
NSNumber *myNum1 = [NSNumber numberWithInt:1];
NSNumber *myNum2 = [NSNumber numberWithInt:2];
NSNumber *myNum3 = [NSNumber numberWithInt:3];
NSArray *a = [NSArray arrayWithObjects: myNum1, myNum2, myNum3, nil];
NSArray *b = [NSArray arrayWithObjects: myNum1, myNum2, myNum3, nil];
int sum=0;
for (int i=0; i<[a count]; i++) {
NSLog(#"%#", (NSNumber*)[a objectAtIndex:i]);
sum =sum +[(NSNumber*)[a objectAtIndex:i] intValue]*[(NSNumber*)[b objectAtIndex:i] intValue];
}
NSLog(#"Sum is %d", sum);
Hope this helps

Iterating backwards over an array throwing exception

I am trying to make an add method that works like long addition, so I want to start the addition from the end and work my way backwards so I can get the carrys right and etc. So I am currently trying to start working backwards over the array.
For example what im trying to do.
two arrays with the character 123456789
and i want to add them starting at 9 + 9 then move to 8+8
So I'm pretty sure I'm using the right way to iterate backwards over an array, but everytime I try I get just the runtime error, index out of bounds, and I can't figure out why. Any help would be great, I just cant figure out why it keeps throwing the exception.
-(MPInteger *) add: (MPInteger *) x
{
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray arrayWithCapacity:100];
//for (int i = 0; i < [a count]; i++) {
for (NSInteger i = [a count] - 1; i > 0; i--) {
int num = 10;
NSNumber *ourNum = [NSNumber numberWithInt:num];
NSNumber *total = [NSNumber numberWithInt:[[a objectAtIndex:i] intValue] + [[b objectAtIndex:i] intValue]];
if ([total intValue] >= [ourNum intValue]) {
total = [NSNumber numberWithInt:([total intValue] - [ourNum intValue])];
[c addObject:[NSNumber numberWithInt:([total intValue])]];
} else {
[c addObject:[NSNumber numberWithInt:[[a objectAtIndex:i] intValue]+[[b objectAtIndex:i] intValue]]];
}
NSLog(#"%#", c[i]);
}
return x;
}
First, let's clean up this code.
- (MPInteger *)add:(MPInteger *)x {
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray arrayWithCapacity:100];
for (NSInteger i = [a count] - 1; i > 0; i--) {
int num = 10;
NSNumber *ourNum = #(num);
NSNumber *total = #([a[i] intValue] + [b[i] intValue]);
if ([total intValue] >= [ourNum intValue]) {
total = #([total intValue] - [ourNum intValue]);
[c addObject:#([total intValue])];
} else {
[c addObject:#([a[i] intValue] + [b[i] intValue])];
}
NSLog(#"%#", c[i]);
}
return x;
}
Next, let's remove redundant/duplicate code.
- (MPInteger *)add:(MPInteger *)x {
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray arrayWithCapacity:100];
for (NSInteger i = [a count] - 1; i > 0; i--) {
int num = 10;
NSNumber *total = #([a[i] intValue] + [b[i] intValue]);
if ([total intValue] >= num) {
total = #([total intValue] - num);
}
[c addObject:total];
NSLog(#"%#", c[i]);
}
return x;
}
Now we can clearly see all of the issues.
You're going from [a count] - 1 to 1. You should be going all the way to 0.
a and b might have different sizes, so if you only do [a count] - 1 to 0, then if for example [b count] < [a count], you'll get an index out of bounds error when you try to access b[i].
You're adding stuff to the end of c, but you should be adding it to the beginning of c since you're iterating backwards.
You don't store the carry anywhere.
You are accessing c[i], which doesn't exist.
You are starting with an empty array 'c', and you NSLog c[i] which is obviously out of bounds on the first iteration.

Get matched string from two NSArrays

How can I save the string that match from one NSArray with one index difference in NSMutableArray?
For example, there are three "apple", four "pineapple", six "banana", two "cocoa" and the rest of words dont have duplicate(s) in the nsarray, i would like to know if the nsarray has at least two same words. If yes, I would like to save "apple", "pineapple, "banana" and "cocoa" once in nsmutablearray. If there are other alike words, I would like to add them to namutablearray too.
My code (which still doesn't work properly);
NSArray *noWords = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:#"words" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL]
componentsSeparatedByString:#"\n"]];
NSUInteger scount = [noWords count];
int ii = 0;
NSString *stringline;
for (ii; ii < scount; ii++)
{
stringline = [noWords objectAtIndex:ii];
NSLog(#"stringline : %# ", stringline);
}
int i = 1;
NSString *line;
for (i ; i < 10; i++)
{
line = [noWords objectAtIndex:i];
NSLog (#"line : %# ", line);
NSMutableArray *douwords = [NSMutableArray array];
if ([stringline isEqualToString:line])
{
NSString *newword;
for (newword in douwords)
{
[douwords addObject:newword];
NSLog (#"detected! %# ", douwords);
}
}
}
Here's a solution using two sets:
- (NSArray *)getDuplicates:(NSArray *)words
{
NSMutableSet *dups = [NSMutableSet set],
*seen = [NSMutableSet set];
for (NSString *word in words) {
if ([seen containsObject:word]) {
[dups addObject:word];
}
[seen addObject:word];
}
return [dups allObjects];
}
Assuming NSSet uses hash tables behind the scenes (which I'm betting it does), this is going to be faster than the previously suggested O(n^2) solution.
Here's something off the top of my head:
NSMutableSet* duplicates = [NSMutableSet set];
NSArray* words = [NSArray arrayWithObjects:#"Apple", #"Apple", #"Orange", #"Apple", #"Orange", #"Pear", nil];
[words enumerateObjectsUsingBlock:^(NSString* str, NSUInteger idx, BOOL *stop) {
for (int i = idx + 1; i < words.count; i++) {
if ([str isEqualToString:[words objectAtIndex:i]]) {
[duplicates addObject:str];
break;
}
}
}];
NSLog(#"Dups: %#", [duplicates allObjects]); // Prints "Apple" and "Orange"
The use of an NSSet, as opposed to an NSArray, ensures strings are not added more than once. Obviously, there are optimizations that could be done, but it should be a good starting point.
I assume that you want to count appearances of words in your array and output those with a count of more than one. A basic and verbose way to do that would be:
// Make an array of words - some duplicates
NSArray *wordList = [[NSArray alloc] initWithObjects:
#"Apple", #"Banana", #"Pencil",
#"Steve Jobs", #"Kandahar",
#"Apple", #"Banana", #"Apple",
#"Pear", #"Pear", nil];
// Make an mutable dictionary - the key will be a word from the list
// and the value will be a number representing the number of times the
// word appears in the original array. It starts off empty.
NSMutableDictionary *wordCount = [[NSMutableDictionary alloc] init];
// In turn, take each word in the word list...
for (NSString *s in wordList) {
int count = 1;
// If the word is already in the dictionary
if([wordCount objectForKey:s]) {
// Increse the count by one
count = [[wordCount objectForKey:s] intValue] + 1;
}
// Save the word count in the dictionary
[wordCount setObject:[NSNumber numberWithInt:count] forKey:s];
}
// For each word...
for (NSString *s in [wordCount keysOfEntriesPassingTest:
^(id key, id obj, BOOL *stop) {
if ([obj intValue] > 1) return YES; else return NO;
}]) {
// print the word and the final count
NSLog(#"%2d %#", [[wordCount objectForKey:s] intValue], s);
}
The output would be:
3 Apple
2 Pear
2 Banana

How to simplify my code... 2D NSArray in Objective C...?

self.myArray = [NSArray arrayWithObjects: [NSArray arrayWithObjects: [self generateMySecretObject], [self generateMySecretObject],nil], [NSArray arrayWithObjects: [self generateMySecretObject], [self generateMySecretObject],nil],nil];
for (int k=0; k<[self.myArray count]; k++) {
for(int s = 0; s<[[self.myArray objectAtIndex:k] count]; s++){
[[[self.myArray objectAtIndex:k] objectAtIndex:s] setAttribute:[self generateSecertAttribute]];
}
}
As you can see this is a simple 2*2 array, but it takes me lots of code to assign the NSArray in very first place, because I found that the NSArray can't assign the size at very beginning. Also, I want to set attribute one by one. I can't think of if my array change to 10*10. How long it could be. So, I hope you guys can give me some suggestions on shorten the code, and more readable. thz
(Some Assumptions: myArray will have a fixed size. It won't grown up or become smaller in the run time.)
Generate the array by -addObject:.
NSMutableArray* myArray = [NSMutableArray array];
for (int k = 0; k < 10; ++ k) {
NSMutableArray* subArr = [NSMutableArray array];
for (int s = 0; s < 10; ++ s) {
id item = (s == 0 && k == 0) ? [self d] : [self generateMySecretObject];
[item setAttribute:[self generateSecertAttribute]];
[subArr addObject:item];
}
[myArray addObject:subArr];
// use [myArray addObject:[[subArr copy] autorelease]] for deep immutability.
}
return [[myArray copy] autorelease];
(Don't query self.myArray many times. Each corresponds to an ObjC call and while someone calls an ObjC call is cheap, it's still not free.)
If the array is a fixed size and each row is the same length then you could uses a 1D array and an offset, EG:
int rowLength = 5;
int rowNumber = 0;
int columnNumber = 3;
[myArray objectAtIndex: (rowLength * rowNumber) + columnNumber];