How to reorder an Array of Dictionaries as per random order of keys/attributes (neither ascending nor descending) [duplicate]

StackOverflow https://stackoverflow.com/questions/17339563

Question

I have an array of dictionaries as below.

NSMutableArray *newArray
({
    {
        A = John;
        B = THAILAND;
    },
    {
        A = Jack;
        B = US;
    }
    {
        A = Lee;
        B = BRAZIL;
    }
    {
        A = Brandon;
        B = UK;
    }
    {
        A = Jill;
        B = JAPAN;
    }
    {
        A = Johnny;
        B = UK;
    }
    {
        A = Amar;
        B = AUSTRALIA;
    }
})

I want to reorder the above array on the basis of another array (Key B of newArray) which is

NSArray *sortArray = [[NSArray alloc] initWithObjects"US",@"UK",nil];

That means my final array should contain US values first followed by UK followed by the rest. In short, how can I set my own order for an attribute/key in an Array.

How can I do that?

Expected Result :

NSMutableArray *finalArray
({
    {
        A = Jack;
        B = US;
    },
    {
        A = Brandon;
        B = UK;
    }
    {
        A = Johnny;
        B = UK;
    }
    {
        A = John;
        B = THAILAND;
    }
    {
        A = Lee;
        B = BRAZIL;
    }
    {
        A = Jill;
        B = JAPAN;
    }
    {
        A = Amar;
        B = AUSTRALIA;
    }
})

I have tried the below code which gives me ascending order of the key B.

[newArray sortUsingDescriptors:[NSArray arrayWithObjects: [[NSSortDescriptor alloc] initWithKey:@"B" ascending:YES], nil]];
Was it helpful?

Solution 2

For sorting the array of dictionaries based on a particular key which is neither in ascending nor in descending order, but in a random user defined order, I have written the following code using NSPredicate and I got the expected result.

NSMutableArray *filterArray = [[NSMutableArray alloc] init];
        NSArray *sortArray = [[NSArray alloc] initWithObjects:@"US",@"UK",@"THAILAND",@"BRAZIL",@"JAPAN",@"AUSTRALIA",nil];  // Array containing all the distinct value for the key 'Currency' in self defined order (neither descending nor ascending order).
        NSPredicate *predCurrency = nil;
        // Creating the predicate for individual objects in the sortArray and appending it to the filterArray.
        for (int i = 0; i < [sortArray count]; i++) {
            predCurrency = [NSPredicate predicateWithFormat:@"(NEW_KEY_22 contains[cd] %@)",[sortArray objectAtIndex:i]];
            [filterArray addObjectsFromArray:[myNewArray filteredArrayUsingPredicate:predCurrency]];
        }
        NSLog(@"%@",filterArray);
        // Finally setting the filterArray to the array controller.
        [commercialArrayController  addObjects:filterArray];     // This gives the resultant array having the defined order in sortArray.

OTHER TIPS

You're probably going to have to do something like:

[newArray sortUsingComparator:
    ^NSComparisonResult (id a, id b)
    {
        NSUInteger indexOfA = [sortArray indexOfObject:[a objectForKey:@"B"]];
        NSUinteger indexOfB = ...same thing for b...;

        return [@(indexOfA) compare:@(indexOfB)];
    }];

So write your own comparator block that uses the self-defined ordering array to give each object an index and then compares the indices. I've then left NSNumber to return the correct comparison result as it expresses the correct idea, in practice you might want to skip the implied object creation.

To be fully deterministic you'd probably want to do a sort on the other field when indices are equal.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top