0

I am trying to get the compare an object in an NSArray with two objects in two different NSArrays and i want to store the first occurence of the object and discard the next.

e.g:-

I have an Array1 where it contains objects like (20.12, 20.15, 21.4, 22.6, 23.0, 24.2, 28.7, 30.5, 30.9, 32.6, 33.7). Now i have another Array2 that contains objects like (20.00, 22.0, 28.0, 30.0, 33.0) and another Array3 that contains objects like (21.0, 24.0, 29.0, 32.0, 34.0)

Now i want to store the first objects that are in between (20.00 - 21.0, 22.0 - 24.0, 28.0 - 29.0, 30.0 - 32.0, 33.0 - 34.0). I have tried to implement this by using

if (clickTimeInterval >= [[Array2 objectAtIndex:i] doubleValue] && clickTimeInterval <= [[Array3 objectAtIndex:i] doubleValue]) {

My clickTimeInterval is the time interval stored in my Array1. I am able to get the values but i just want to store the values that comes first and store into Array4. It looks something like Array4 = (20.12, 22.6, 24.2, 28.7, 30.5, 33.7). Can anyone please help me out on how to get this?

1
  • Just Create NSMutableArray and add Cliktervel in it Commented Jun 4, 2012 at 12:40

3 Answers 3

2

It depends on how optimized you want to be. Here's a version that re-samples "Array1" for each range. If you have a large number of objects to filter (and they are sorted), you could store the last found location to make subsequent searches quicker.

- (NSArray *)bucketTest {
    NSMutableArray *result = [NSMutableArray array];

    NSArray *samples = [NSArray arrayWithObjects:[NSNumber numberWithDouble:1.1], [NSNumber numberWithDouble:1.5], [NSNumber numberWithDouble:2.2], nil];
    NSArray *lows = [NSArray arrayWithObjects:[NSNumber numberWithDouble:1.0], [NSNumber numberWithDouble:2.0], nil];
    NSArray *highs = [NSArray arrayWithObjects:[NSNumber numberWithDouble:2.0], [NSNumber numberWithDouble:3.0], nil];
    for (int bucket = 0; bucket < [lows count]; bucket++) {
        double low = [[lows objectAtIndex:bucket] doubleValue];
        double high = [[highs objectAtIndex:bucket] doubleValue];
        for (NSNumber *sample in samples) {
            if (([sample doubleValue] >= low) && ([sample doubleValue] < high)) {
                [result addObject:sample];
                break;
            }
        }
    }
    return result;
}
Sign up to request clarification or add additional context in comments.

Comments

2

Improving efficiency of the first answer. Here I am assuming that all arrays are sorted

Make one more array that we will change in each iteration

NSArray *array5 = [array1 copy];

NSMutableArray *array4 = [NSMutableArray array];
for (int i=0; i < array2.count; i++) {
    NSNumber *bottom = [array2 objectAtIndex:i];
    NSNumber *top = [array3 objectAtIndex:i];
    NSPredicate *greaterThanPredicate = [NSPredicate predicateWithFormat:
                                         @"SELF > %@", bottom];
    NSMutableArray *arrayWithBiggerObjects = [NSMutableArray arrayWithArray:[array5 filteredArrayUsingPredicate:greaterThanPredicate]];

    if (arrayWithBiggerObjects.count) {
        NSNumber *lowestObject = [arrayWithBiggerObjects objectAtIndex:0];
        if ([lowestObject compare:top] == NSOrderedDescending) {
            [array4 addObject:lowestObject];
            [arrayWithBiggerObjects removeObject:lowestObject];
            array5 = arrayWithBiggerObjects;
        }
    }
}

Comments

1

Assuming that

  1. All arrays are ordered ascending
  2. array2.count == array3.count
  3. The nth object of array2 is smaller than the nth object of array3

you can do the following

NSMutableArray *array4 = [NSMutableArray array];
for (int i=0; i < array2.count; i++) {
   NSNumber *bottom = [array2 objectAtIndex:i];
   NSNumber *top = [array3 objectAtIndex:i];
   NSPredicate *betweenPredicate = [NSPredicate predicateWithFormat:
      @"SELF > %@ && SELF < %@", bottom, top]; 
   NSArray *inRange = [array1 filteredArrayUsingPredicate:betweenPredicate];
   if (inRange.count) {
      [array4 addObject:[inRange objectAtIndex:0]];
   }
   else {
      [array4 addObject:[NSNull null]]; // or don't add anything
   }
}

2 Comments

if (inRange.count) { [array4 addObject:[inRange firstObject]]; } In the mentioned code an NSArray doesn't declare a method with selector 'firstObject'... Can u please check it once?
Sorry, it should be objectAtIndex:0. Corrected the answer. (There is method lastObject, so I just assumed there is also one for firstObject.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.