Vin
Vin

Reputation: 456

Remove array elements and add them at the same index iOS

I am sorting an array. There are three types of elements in the array. 1. featured 2. organic and 3. claimed.

Among them, I want to sort only organic elements and keep the featured and claimed elements at their own index.

Below is my code in which, I am extracting the claimed and featured indices in a dictionary as key being the index and value is the array element.

//Initialization
NSMutableArray *sortedArray = nil;
NSMutableDictionary *tempFeaturedDictionary = [[NSMutableDictionary alloc]init];
NSMutableDictionary *tempClaimedDictionary = [[NSMutableDictionary alloc]init];
NSMutableArray *tempOrganicArray = [[NSMutableArray alloc]init];

for (int i = 0; i < array.count; i++) {

    DRListing *isFeaturedObj = (DRListing*)[array objectAtIndex:i];

    if (isFeaturedObj.featured) {
        [tempFeaturedDictionary setObject:isFeaturedObj forKey:[@(i)stringValue]];
    }else if (isFeaturedObj.claimed)
    {
        [tempClaimedDictionary setObject:isFeaturedObj forKey:[@(i)stringValue]];
    }else
        [tempOrganicArray addObject:isFeaturedObj];

}

Again I am adding the claimed and featured back to their original indices after sorting as:

 sortedArray = [NSMutableArray arrayWithArray:[tempOrganicArray sortedArrayUsingDescriptors:sortDescriptorsArray]];

for (int i = 0; i<sortedArray.count; i++) {
    for (NSString *key in tempFeaturedDictionary) {
        if ( [[@(i)stringValue] isEqualToString: key] ) {
            [sortedArray insertObject:[tempFeaturedDictionary objectForKey:[@(i)stringValue]] atIndex:i];
        }}

    for (NSString *key in tempClaimedDictionary) {
        if ([[@(i)stringValue]isEqualToString:key ]) {
            [sortedArray insertObject:[tempClaimedDictionary objectForKey:[@(i)stringValue]] atIndex:i];
        }
    }
}

The code works good. Except there is claimed/(and)featured elements at the last index of the 'array'. Because the 'sortedArray' index remains less than the 'array.count' in this scenario. Thanks in advance.

Update -

I receive response array of type:

[{featured1 featured2}, {organic1, organic2..}, {claimed1}, {featured11, featured12}, {organic11, organic12..}, {claimed2}, ..]

and I am allowed to sort only organic elements within this array. Featured and claimed should not loose their original index position.

Upvotes: 0

Views: 494

Answers (3)

Murat Tezyapar
Murat Tezyapar

Reputation: 142

You can take the first 2 functions. The others are what I used for testing.

- (DRListing *)getNextObjectFromArray:(NSArray *)array WithStartingIndex:(int)index
{
    for (int i=index; i<array.count; i++) {
        DRListing *obj = (DRListing*)[array objectAtIndex:i];
        if (!obj.featured && !obj.claimed)
        {
            return obj;
        }
    }

    return nil;
}

- (void)sortArray:(NSMutableArray *)array
{
    for (int pass = 0; pass<array.count-1; pass++) {
        for (int i=0; i<array.count-1; i++) {
            DRListing *obj = [self getNextObjectFromArray:array WithStartingIndex:i];
            int foundIndex = (int)[array indexOfObject:obj];
            DRListing *obj2 = [self getNextObjectFromArray:array WithStartingIndex:foundIndex+1];
            int foundIndex2 = (int)[array indexOfObject:obj2];

            if (obj!=nil && obj2 !=nil) {
                if (obj.value >= obj2.value) {
                    [array exchangeObjectAtIndex:foundIndex withObjectAtIndex:foundIndex2];
                }

                i = foundIndex;
            }
        }
    }

    NSLog(@"Sorted Data: %@",array);
}

- (NSMutableArray *)testData
{
    NSMutableArray *array = [NSMutableArray new];
    for (int i=0; i<20; i++) {
        DRListing *obj = [DRListing new];
        obj.featured = i*i%2;
        obj.claimed = i%2;
        obj.value = i*3%10;
        [array addObject:obj];
    }

    NSLog(@"Test Data: %@",array);
    return array;
}

@interface DRListing : NSObject

@property (nonatomic) BOOL featured;
@property (nonatomic) BOOL claimed;
@property (nonatomic) int value;
@end

Upvotes: 0

Paulw11
Paulw11

Reputation: 114865

I would iterate through the array, extracting the organics to sort. Then sort your organic array. Then iterate through the original array taking either the element from the original array or an element from the sorted organics array as appropriate.

NSMutableArray *organicsArray = [NSMutableArray new];

for (int i = 0; i < array.count; i++) {
    DRListing *isFeaturedObj = (DRListing*)array[i];

    if ((!isFeaturedObj.featured) && (!isFeaturedObj.claimed)) {
        [organicsArray addObject:isFeaturedObj];
    }
} 
NSMutableArray *sortedOrganicsArray = [[organicsArray sortedArrayUsingDescriptors:sortDescriptorsArray] mutableCopy];

NSMutableArray *outputArray = [NSMutableArray new];

for (int i = 0; i < array.count; i++) {
    DRListing *isFeaturedObj = (DRListing*)array[i];

    if ((!isFeaturedObj.featured) && (!isFeaturedObj.claimed)) {
        [outputArray addObject:sortedOrganicsArray[0]];
        [sortedOrganicsArray removeObjectAtIndex:0];
    } else {
        [outputArray addObject:isFeaturedObject];
    }
}

You could possibly make it a little more efficient if you reversed your sort order for the organics array since then you could say

[outputArray addObject:[sortedOrganicsArray lastObject]];
[sortedOrganicsArray removeLastObject];

But if your array isn't particularly large then the performance improvement will probably be negligible.

Upvotes: 1

LoVo
LoVo

Reputation: 2073

Maybe this is an alternative:

NSMutableArray *organics = [NSMutableArray new];
NSMutableArray *others = [NSMutableArray new];

for (DRListing *isFeaturedObj in array) {
     if (isFeaturedObj.organic) {
         [organics addObject:isFeaturedObj];
     } else {
         [others addObject:isFeaturedObj];
     }
 }

 NSMutableArray *sorted = [NSMutableArray alloc]initWithObjects:organics,others, nil];

Upvotes: 0

Related Questions